キャラクターなどを進行方向に振り向かせたい場合はどうすればいいの?
移動量の計算と回転のクォータニオンの計算を活用すれば良いわ。詳しく解説していくね。
オブジェクトを進行方向に振り向かせる方法の解説記事です。
本記事では、次のようにオブジェクトを進行方向に向き続けるような動きを実現することを目標とします。
実装の流れは以下のようになります。
- 移動量を進行方向(ベクトル)として計算
- 進行方向に向く回転(クォータニオン)の計算
- 上記をオブジェクトの回転に反映
進行方向は移動量として求めることができます。
進行方向を向くようなクォータニオンの計算は、一見すると複雑ですが、Unityが提供するヘルパーAPIを用いれば比較的楽に実装できます。
本記事では、このような進行方向に回転させる動きをスクリプトで実装する方法を解説します。また、滑らかに(徐々に)に回転させるような動きの実装方法についても紹介します。
- Unity 2022.1.5f1
目次 非表示
前提条件
移動するオブジェクトがシーン上に配置されているものとします。
このオブジェクトに対して、進行方向に回転するスクリプトを適用していくものとします。
進行方向(移動量)の計算
進行方向は、過去の位置から移動量のベクトルとして計算できます。
進行方向は長さ1に正規化すると都合の良い場合がありますが、本記事では不要のため正規化は行わず、移動量をそのまま進行方向として扱うこととします。
移動量は次式で求めることができます。
移動量 = 現在フレーム位置 – 前フレーム位置
スクリプトでは、次のような形で移動量を計算します。
そして、この移動量は進行方向として、次に解説する回転の計算で使用します。
進行方向を向く回転の計算
進行方向に向くような回転はクォータニオンで表せます。このようなクォータニオンは、Quaternion.LookRotationメソッドから取得できます。
第1引数forwardには、振り向く前方のベクトルを指定します。
第2引数upwardsには、上向きのベクトルを指定します。省略された場合は、Vector3.upという上向きを表すベクトル(0, 1, 0)が指定されます。
参考:Quaternion-LookRotation – Unity スクリプトリファレンス
進行方向を振り向くサンプルスクリプト
以下、移動する方向にオブジェクトを回転させるサンプルスクリプトです。
上記スクリプトをRotateToMovementDirection.csという名前で保存し、回転処理を適用したいゲームオブジェクトにアタッチすると機能するようになります。
進行方向に回転させる際、オブジェクトが静止している状態だと進行方向が定まらないため、この場合は処理しないように対策しています。
実行結果
進行方向に向くときは、移動するオブジェクトの上側がワールド座標上向きになるように計算されています。これは、Quaternion.LookRotationメソッドの第2引数にVector3.upが指定されているためです。
滑らかに回転させる
先述の例では、進行方向に瞬時に回転するようになっていました。
滑らかに回転させたい場合、回転速度に制限を設けたり、ダンピングさせながら角度を徐々に変化させるような計算を行えば良いです。
以下、滑らかに進行方向に回転させるようにしたサンプルスクリプトです。
上記スクリプトをRotateToMovementDirectionSmooth.csという名前で保存し、回転を適用させたいゲームオブジェクトにアタッチすると機能するようになります。
必要に応じて、インスペクターからパラメータを調整してください。
実行結果
急カーブでも滑らかに振り向くようになりました。
スクリプトの解説
滑らかに回転させるための方法はいくつか存在しますが、例ではMathf.SmoothDampAngleメソッドを使用して次に回転すべき角度を計算しています。
Mathf.SmoothDampAngleメソッドは、目標値に滑らかに一致させるような値を求めることができる関数で、目標値に一致するまでの時間や最大の速さなどを設けることが可能です。
参考:Mathf-SmoothDampAngle – Unity スクリプトリファレンス
SmoothDampAngleを含めたSmoothDamp系メソッドの使い方については、以下記事で詳しく解説していますので、必要な方はご覧ください。
そして、以下処理で現在の回転から目標の回転にSmoothDampAngleメソッドで計算した角度分だけ回転したクォータニオンを求めています。
Quaternion.RotateTowardsメソッドは、第1引数のクォータニオンから第2引数のクォータニオンに向かった回転を返すメソッドで、第3引数には最大の回転角度を指定できます。
参考:Quaternion-RotateTowards – Unity スクリプトリファレンス
オブジェクトの前と上の基準を変更する
ここまで解説した例では、移動するオブジェクトのローカル空間のz軸正方向を正面、y軸正方向を上として計算していました。
これらの基準軸を変更したい場合、次のように回転の補正を行えば良いです。
以下、向きの基準変更に対応したサンプルスクリプトです。滑らかな回転にも対応しています。
上記スクリプトをRotateToMovementDirectionOffset.csという名前で保存し、移動対象のオブジェクトにアタッチし、各種設定を行います。
以下は、前方をy軸正方向、上をx軸正方向にした設定例です。
実行結果
向きの基準が変わっていることが確認できます。
スクリプトの解説
以下処理で回転補正を求めています。
Quaternion.Inverseメソッドは、指定されたクォータニオンの逆回転を求めるAPIです。変更された基準軸を戻すような操作を行うことで、今まで通りの回転処理が行えるようになります。
そして、以下処理で回転補正のあとに進行方向に回転するようなクォータニオンを求めています。
参考:Quaternion-Inverse – Unity スクリプトリファレンス
また、基準軸の変更に伴い、正面方向のベクトル計算も変わっています。
特定の軸周りで回転させる
例えばプレイヤーが操作するキャラクターなどを進行方向に向かせたい場合、水平方向(y軸周り)の振り向きに限定したほうが良いでしょう。
以下、指定された軸周りに限定して回転させるようにした例です。滑らかな回転や基準軸の指定処理も含まれています。
上記をRotateToMovementDirectionAxis.csという名前で保存し、移動するオブジェクトにアタッチし、各種パラメータの設定を行います。
以下は、y軸周りで回転させるようにした設定例です。
実行結果
勾配のある移動でも常にy軸周りで振り向くようになっています。
スクリプトの解説
以下のコードで回転軸と垂直な平面に投影したベクトルを求めています。
projectFromは現在のオブジェクトの向きの投影ベクトル、projectToは目標の向きの投影ベクトルです。
参考:Vector3-ProjectOnPlane – Unity スクリプトリファレンス
次の処理で、軸周りの回転角度を計算しています。
そして、軸周りでの回転の開始と終了のクォータニオンを計算します。
最終的な回転の計算は以下のようになります。
回転補正の適用は先の例と同じ要領で出来ます。
さいごに
オブジェクトを進行方向に回転させる方法を紹介しました。
進行方向をベクトルとして計算し、現在のオブジェクトの向きを進行方向に回転させるようなクォータニオンを計算することで求めることで実現可能です。
また、滑らかに回転させる方法はやや複雑ですが、こちらもクォータニオンを駆使することで実現できます。