概要
Unityにおいてオブジェクトを目標の方向に向かせる一般的な方法はTransform.LookAt
だが、これは当然ながら一瞬でオブジェクトの方向が変化してしまう。オブジェクトの方向を時間をかけて変化させ、かつ方向の変化が一定の速度(角速度)になるような方法が欲しかった。
実装
public class SampleObject : MonoBehaviour
{
// 目標
public Transform target;
// 角速度(deg/sec)
float angularVelocity = 90f;
void Update()
{
// 目標の方向
Quaternion rotation = Quaternion.LookRotation(target.position - transform.position);
// 現在の方向と目標の方向がなす角度
float angle = Quaternion.Angle(transform.rotation, rotation);
if (angle > 0)
{
// 経過時間によって変化させる角度
float deltaAngle = angularVelocity * Time.deltaTime;
// オブジェクトの方向を変更
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, deltaAngle / angle);
}
}
}
現在の方向から目標の方向に一定速度で変化させるには、2つの方向の間で任意の角度だけ変化させる必要がある。
Quaternion.Slerp
は引数で指定した2つの方向を第3引数の率で補間するため、第3引数に「変化させたい角度」÷「現在の方向と目標の方向がなす角度」を指定すれば、現在の方向から目標の方向に任意の角度だけ変化させた方向が得られる。なお、第3引数が1を超えた場合、1として扱われるので特に補正は不要である。
用途
NPCがプレイヤーの方向を向く速度を調整することを想定している。例えば以下のようなケースである。
- 敵NPCの背後を取りたい
- 老人NPCをゆっくり動かしたい
- 店主NPCがプレイヤーの方向を向いていない隙に・・・