前回の記事で歩行のモーションを実装したので、今回はスニーク歩きの実装です。
スニーク歩きはいろいろと複雑で、Blenderでモーションを作ってUnityで実装すること両方を考えながら作業を進める必要があったので注意点をまとめてみました。
前後移動と左右移動を作ってモーションを良い感じにブレンドするにはちょっとしたコツが必要そうです…!
もくじ
Unity側の仕様
実際の作業順はBlender→Unityですが、まずUnityのアニメーションの方の話からです。
前回、歩行については停止・歩き・走りモーションを作ってスピードで切り替えるようにしましたが、スニークは正面方向だけでなく左右と後ろへのモーションを切り替える必要があります。
そのため、スピードではなく前後左右の平面でのパラメーターでモーションを切り替えることにしました。
これにはBlend Treeの2D Directionalを使います。
2D Directionalは主にキャラクターの移動に使うためのブレンドで、前後と左右の座標を指定すると角度に応じてそれぞれのモーションをブレンドしてくれます。
ここでの問題は斜め移動です。
前後と左右は専用のモーションを作りますが、斜めは2つのモーションをブレンドした中間のものになります。
別々のモーションの中間の動きなので、色々考えて作らないと動きがおかしくなってしまいます。
最初に何も考えずに作った横移動がこんな感じですが、これは全然駄目でした。
一番の問題点は片足をクロスするように後ろに重ねる動作が入っていることです。
両足の前後の位置がずれているので、これが前後移動の動きと干渉して奇妙な動きになってしまいます。
また片足のかかとを大きく上げているのも動きがおかしくなる原因になっていました。
こういう動きを使いたいなら、2D Directionalでのブレンドを使わない別の方法で実装する必要がありそうです。
(あるいは斜め移動のモーションを全方向分作ればうまくいくかも…?)
Blenderでの制作の注意点
というわけで、Blenderでモーションを作るには2D Directionalの斜めのブレンド結果から逆算して作る必要がありそうです。
まず僕は仕様として、キャラは前後左右に同じスピードで移動させることにしました。
スクリプト的に作りやすくゲーム的にも分かりやすいと思うので、モーションを前後左右同じスピードと距離に合わせて作るようにします。
横移動で足をクロスさせたくないので、前後移動と横移動では横移動の歩幅の方が小さくなります。そのため1回のループで移動する距離は横移動に合わせて決めておきます。
まずは決めた移動距離に合わせて前移動を作って、「その動きが斜め移動になったら?」から引き算をするイメージで横移動を作ると少し作りやすいかなと思いました。

前移動と後ろ移動
- 全体のフレーム数を合わせる
- 足を上げ下げするタイミングを合わせる
- 最初に動かす足を同じ足にする
横移動
- 足の前後の動きは作らない
- フレーム数や足の上げ下げのタイミングは前後移動と合わせる
- 足の上げ下げによるかかとや足裏の動きは小さめにしておく
- 最初に動かす足を前後移動と同じにする
思わぬ落とし穴として、最初に動かす足を逆にした場合(前移動は左足から踏み出し&後ろ移動は右足から踏み出し)、斜め後ろのブレンドがグチャグチャになってしまったので要注意です。
同じ足から開始するようにしたところ、良い感じにブレンドされるようになりました。
ただし横移動は片方だけ作ってミラーを設定すればOKで、ブレンドにも問題なさそうでした。
制作の際はBlender上でブレンド結果の確認ができないので、大まかに作ったところでUnityに持って行ってブレンドの確認をしながら進めるのが良いかと思います。
Unityの設定方法
Blend Treeの2D Directionalの設定方法です。
2D DirectionalはSimpleとFreedomの2種類があり、Freedomだと同じ方向に複数のアニメーションを設定できますが、今回は複数設定するつもりではないので2D Simple Directionalを使います。
また前回の記事でBlend Treeの1Dの設定方法をまとめているので、基本的な作り方はそちらを見てみてください。
まずAnimationが受け取れるパラメーターはX座標とZ座標の2つをFroatで用意します。今回はSneakXとSneakZという名前にしてみました。
これを2D Directionalの2つのパラメーターとして設定します。


その他、スニーク状態に入るためのBoolのパラメーターも用意しました。これはBoolがtrueになった時にMoveから遷移するように設定すればOKなだけなので、この記事では省きます。
僕は今回、「静止」「前移動」「後ろ移動」「右移動」の4つのモーションを用意しています。(左移動は右移動のミラーとして設定します)
Motionを5つ用意し、それぞれPosXとPosYの値を設定します。(平面なのでXとYですが実質XとZです)
ミラーはチェックするだけで大丈夫です。

PosX | PosY | |
前移動 | 0 | 1 |
右移動 | 1 | 0 |
後ろ移動 | 0 | -1 |
左移動 | -1 | 0 |
停止 | 0 | 0 |
こんな感じになればOKです。

スクリプトからの指定
スニーク歩行のブレンドを正しく動かすには、キャラクターの向きを正面にした場合の移動方向のXZ座標を算出する必要があります。
これはプレイヤーキャラのQuaternion(Y軸のみ回転のもの)と現在の移動方向のベクトル(XZ方向のみのもの)が分かればQuaternion.Inverseを使って補正されたベクトルを算出できます。
Animator animator;
void FixedUpdate()
{
Vector3 sneakDir = Quaternion.Inverse(player.transform.rotation) * towardDir;
animator.SetFloat("SneakX", sneakDir.x);
animator.SetFloat("SneakZ", sneakDir.z);
}
また、スニーク移動をしている最中はキャラクターが回転しないようにしておくと良いかと思います。
出来上がり
足がやや滑るような感じで不自然な時もありますが、僕としては許容範囲内です…!
キャラクターのスピードや方向を自由に変更できる状況で、動きが固定された5つのモーションだけを使ってここまで出来るのならこれでいいかなと思います。
次回はジャンプ移動の動きを作ろうと思います!
ジャンプができるようになればアクションの基本の動きは一通りできることになるかなと思います。
次回も見ていただけたら嬉しいです!
その他のアニメーション実装の記事はこちら↓