スクリプトベースで移動するキャラクターにアニメーションを合わせる方法

足滑りを回避するには

スクリプトベースで移動するキャラクターにアニメーションを設定すると、不自然に足滑りを起こす…なんて事ありますよね。
この動画ではスクリプトで制御されたキャラクターの挙動はそのままに、あまり不自然にならないようにアニメーションを合わせる方法を紹介します。

まずはキャラの変更から

まずは簡単に、動くキャラクターを用意しました。RigidbodyでVelocityを直接変更させて動かしています。
このキャラができることは入力に応じた左右に移動、ジャンプ、ダッシュなどです。

さて最初に、ビジュアルを帽子を被ったカプセルから、赤い男に変更します。
カプセルのキャラクターを非表示にした後キャラクターの下にモデルを配置して、位置を調整。Apply Root MotionはOffにしておきます。再生するとエスパーキャラでよくある固定ポーズの移動が見れます。このとき、足の位置が概ね接地できてることを確認します。

モーションの設定

次はスクリプトを記述してAnimatorにキャラクター自身の状況と、周囲の環境を伝えます。左スティックの入力を取得してスティックを倒した分だけの速度をSpeedに設定。ピーキーに動き過ぎるのでダンプ値も設定しておきます。スクリプトと先ほど追加したモデルのAnimatorの関連付けをしたらスクリプトから渡されたパラメーターを元に再生すべきアニメーションを選択する部分を作ります。

AnimatorControllerでSpeedに応じてアニメーションを切り替えるステートマシンを作ります。
今回は無段階で切り替わるアニメーションなのでBlendTreeを使います。BlendTreeでLocomotionを作成し、FootIKにチェックを入れ、Locomotionにアイドリング、歩行、ランニングスプリントを追加します。

歩行モーションの切り替え

シーンを再生すると移動時にモデルもアニメーションします。しかし足が盛大に滑っているように見えます。

なのでスクリプトでキャラクターが移動する速度とアニメーションが想定する移動測度を概ね一致させることで修正する方法を解説します。

具体的には、スクリプトでキャラクターが移動する速度とアニメーションが想定する移動測度を概ね一致させます。ここでのポイントはBlendTreeのパラメータのAutomate thresholdsを外し、Compute ThresholdsでVelocity Zを指定する事です。

これはRootMotionを持っているアニメーションクリップの、移動速度の平均値を自動で設定する機能であり、アニメーションが移動する速度が取得できます。今回選択したVelocity Zなら、キャラクターが前方に移動する速度が入力されます。

アニメーション側の移動速度が取得できたら、後はスクリプトの移動速度をAnimatorに渡します。この移動速度はRigidbodyやNavMeshAgentであればVelocityが、独自のスクリプトで移動している場合はDeltaTimeを乗算する前の値が該当します。

この二つによって、キャラクターの移動速度と一致する形でアニメーションが選択/ブレンドされる形になり、結果としてキャラクターの移動時に足を滑らすことがなくなります。

なお、これはあくまで概ねの一致なのでできるだけモーションの移動速度と実際の移動速度が一致するようにした方が、きれいな動作になります。また等身や身長が(リグと比較して)大きく異なるケースではうまく動作しないので身長差に応じてアニメーション再生スピードを補正するなどの調整が必要です。

歩行以外のモーション設定

ジャンプや着地といったモーションの場合はどうでしょう。
現状だとジャンプしたとき空中でも足をバタつかせる動作をするので、これを直していきます。
まずはジャンプ時のモーションの切り替えが必要なので、Animatorにキャラクターの現状の情報、つまり落下速度と地面に接地しているかを伝えます。あとは、これらのパラメーターを元にAnimatorControllerに、現在取るべきアニメーションを判断してもらいます。

空中モーションの切り替え

IsGroundがtrueになったときにはSpeedに応じて着地モーションを切り替えます。
BlendTreeを使用し、移動スピードの変化に即座に対応できるようにしておきます。これで完成です。

では、また別の動画でお会いしましょう!