Unityで物理演算でTPS型のキャラ移動を作る記事の続きです。
少し前の記事でプレイヤーキャラのオブジェクトが物理演算で勝手に回転しないようにしてしまったので、今回は回転の処理を作っていきます。
前回の記事はこちらです!↓
もくじ
オブジェクトの構造
まず分かりやすいように目をつけてみました。

カワイイ!
プレイヤーキャラの床・壁判定用のオブジェクトは物理演算で動いており、Freeze Rotationを全ての軸でチェックして回転しないようになっています。
まずはキャラの回転用オブジェクトをEmptyのオブジェクトで作り、床・壁判定オブジェクトの子にします。
これをスクリプトからTransform.rotationで回転させることになります。
3Dモデルは更に回転用オブジェクトの子にして一緒に回転させます。
(キャラを変更する機能を作るなら3Dモデルは子オブジェクトにした方が扱いやすそうなので、とりあえず子にしてみました)
回転の方向と値
それでは回転の処理を作っていきます。
まず仕様としてキャラの回転はy軸のみにすることにします。ダメージなどの当たり判定は3Dモデルと連動するようにする予定ですが、キャラの向く方向はy軸に限定してしまいます。
プレイヤーキャラの正面はキャラの移動方向と同じということになります。
ただしプレイヤーの入力は急に反転したりすることもあるので、全く同じにしてしまうとキャラが突然反転するように見えて不自然です。
そのため、現在の向きから移動方向に滑らかに移り変わるようにします。
前回の記事の目的地へ移動する割合と処理内容は似ていますが、今回は方向なのでQuaternion.LerpかQuaternion.Slerpを使ってみようと思います。
LerpとSlerpを図にするとこんな感じです。

赤矢印が現在のキャラの向き、青矢印が目的の向き(移動方向)とした時に毎フレーム必ず一定割合だけ向きが近づく(紫矢印)ようにします。
なおLerpの方が処理は軽いものの、aとbの差が大きい時にはSlerpの方が滑らかな補間の角度を算出できるそうです。図を見るとなんとなく分かりますね。
どちらが良いかは後ほど比べてみようと思います。
現在のキャラの向きのQuaternionは回転用オブジェクトのTransform.rotationです。
移動方向のQuaternionは移動用スクリプトの方からVector3の移動方向が取得できるので、Quaternion.LookRotation(Vector3 方向)を使ってQuaternionに変換します。
ただし移動方向のVector3はx軸とz軸の方向も入っているので、xz軸回転が反映される前のy軸だけのものを取得できるようにしておきます。
この2つをLerpかSlerpの引数にすればTransform.rotationに指定するQuaternionが分かります。
transform.rotation = Quaternion.Lerp( 現在のキャラの向き, 移動方向の向き, t ); のような感じです。
tの値はどのくらいの速さで向きを回転させるかで、0.0fなら全く向きを変えず1.0fなら即座に方向転換するようになります。
色々変えて試して良い値を見つけるのが良いかなと思います。
LerpとSlerpの比較
実際の動作は手で動かしているので同じ動きではないですが、どうでしょう?
Lerp
Slerp
ちなみに僕はほぼ全く分からないです。Slerpの方が等速っぽい感じで回転していてLerpは回転の角度が大きい時の回り方が早い…でしょうか?
それもある意味ではイージングのようにも見えるので、Lerpの方がカクついているとかぎこちないとかは思わないです。
なおLerpとSlerpで処理の重さが違うという点も、プレイヤーキャラ1体の毎フレーム1回の処理でStatisitcsで見て分かるような感じではないです。
「これを直したら重かったゲームが軽くなった!」とかにはならないような気がします。
ゲームをしている時にキャラそのものの動作を凝視している人ってあまりいない(周囲の構造物や敵などを見ていることの方が多い)と思うので、好みでどっちでもいいのかな…と。
まとめ
LerpとSlerpはとても便利なので覚えておきたいです。
作り始めた当初は「それぞれの角度をfloatにしてLerp…?」と思っていましたが、Lerpにもfloat・Vector3・Quaternionなどいろいろあるので最適なものを使えるようにしておくとよさそうです。
次回の記事はこちら↓