前回までの記事で歩行とスニーク歩きのモーションを実装したので、今回は基本的な動きの中で最後になるジャンプモーションの実装です!
ゲームの仕様でジャンプの高さや横方向の移動距離をプレイヤーが制御できる場合、ジャンプモーションを良い感じに実装するのはちょっと工夫が必要です。
今回の記事では僕のモーションの作り方とUnityでの実装についてまとめてみました。
もくじ
モーションの制作
まず、僕が今作っているゲームでは移動に物理演算を使っていてジャンプの高さと移動距離は物理演算の加える力で変わります。
そのため、まずモーション制作の時点で色んな状況に対応できるようにしておきます。
今回僕が作ったのは「上昇」「下降」「着地」の3種類です。
これを「その場でジャンプ」「前方へジャンプ」の2種類で計6個作りました。
こんな感じです。
その場でジャンプ
前方へジャンプ
ポイントとして、いろんなジャンプに対応するためつなぎ目になる上昇モーションの後半と下降モーションの終わりはふわっとした動きにして長さを長めにしておきます。
歩行モーションと同様に、ジャンプは飛び上がる仕草だけを作って前移動や上下移動は入れないようにします。
またゲームオブジェクトそのものがジャンプの際に上下に動くので、飛んでいる間の頭の高さはあまり変わらないようにして足や腰を曲げる動作で足が浮く分だけを作りました。
またこれはゲームの仕様や雰囲気によりますが、上昇する際に一旦踏み込む動作を作るかどうかは気を付けた方がよさそうです。
物理演算のオブジェクトはAddForceしたらすぐ飛び上がるので、踏み込みをきれいに見せたいならAddForceのタイミングをずらす必要があります。
これがプレイヤーの操作とのズレになるので、アクションゲームだとかなりの違和感があります。
またアクションゲームで連続ジャンプの間隔が短めの場合、スムーズにアニメーションをつなげるのが難しくなります。
自然な動き重視なのか操作性重視なのかで割り切って決める必要があるかなと思います。
Animation Clipの設定

Animation Clipの設定は前の記事とほぼ同様です。
今回のモーションはループさせる必要がないのでオフにします。モーションが終わった後は静止することになります(そのため先述のとおりモーションの終わりは長めにとっておきます)。
またBlenderで頭の高さが変わらないようにモーションを作ったので、Based UponはOriginalにします。
Animatorの設定
今回は切り替えが複雑になるので、Blend Treeではなくステートの遷移でモーションを変えることにしました。
まずその場ジャンプの設定から作ります。
こういう遷移の場合、パラメーターはTriggerかIntegerが良いのかなと思います。
ただしどちらもジャンプの実装をするには注意点があります。
Trigger
TriggerはスクリプトからSetTrigger()を実行した際にステートの遷移を開始し、遷移が終わったら自動的にオフになります。ただし遷移中に別のTriggerがセットされた場合はすぐに開始するのではなく予約状態になり、前の遷移が終わってから遷移が実行されます。
すぐに変えたい場合はResetTrigger()で前の遷移をキャンセルする必要があります。(直前に実行されていた可能性のある全部のTriggerに対して処理する必要があるので注意です)
また遷移の条件ごとに1つ1つ別のパラメーターとして作る必要があります。
Integer
IntegerはSetInteger()の引数に指定する値を変えることによって1つのパラメーターで複数の遷移を処理することができます。ただし、どの値がどの遷移に対応するのかは手作業で管理する必要があります。
また、値の中に「待機状態」(ジャンプしていない状態)の値を用意しておき、最後の遷移が終わったと思われるタイミングで値を戻す必要があります。
両方試してみましたが、Triggerは扱いが難しい気がしたので今回はIntegerで実装することにしました。
「Jump_State」という名前で1つパラメーターを作成します。

パラメーターの準備ができたら、次にAnimatorのウインドウの空いたところを右クリックしてステートを3つ作ります。3つのステートは右クリックしてMake Transitionでトランジションを作ってつなぎます。

ここでの注意点ですが、この3つのステートはすべて双方向になるようにつなぎます。
僕の場合、「上昇→下降」「下降→着地」「上昇→着地」はあっても「下降→上昇」はスクリプト的にあり得ないから必要ない…と最初思っていました。
でもステート的には「遷移が終わっていないので下降→上昇」などのケースが発生するようです(連続ジャンプのつなぎ目など)。
遷移を作っていないと動きが止まって変になってしまうので要注意です。
また同様にMove(歩行ステート)との遷移について、どのステートからでもMoveに戻れるようにしておきます。
遷移の設定
ステートの遷移にはいくつか設定が必要です。
それぞれのトランジションの矢印をクリックすることで設定をすることができます。

①Has Exit Timeの設定
そのステートのアニメーションが終わったら自動で遷移するかどうか?という設定です。遷移しない場合、最後のフレームの状態で静止することになります。
今回Jump_UpとJump_DownはHas Exit TimeをオフにしてJump_Landはオンにしました。
これで着地したら自動で歩行に戻ることができます。
②切り替えの長さの設定
Blend TreeではFloatなどの指定でアニメーションのブレンド割合が決まりますが、ステートの遷移の場合はブレンドする時間の長さを指定できます。
ジャンプの踏み切りや着地がもたつく場合、ブレンドする時間が短くなるように調整すればOKです。
③Conditionsの設定
どのパラメーターの際に遷移するか?という設定です。
今回はIntの値を事前に自分で決めておき、それぞれの値を指定します。
スクリプトからの処理
スクリプトからの処理は簡単で、必要なタイミングで Animator.SetInteger(“Jump_State”, 1); みたいな感じで1回だけ実行すればOKです。
Intの値なので、どれがどれなのか自分で分かるようにしておく必要があります…。
走りジャンプの踏み切り足
次は走りジャンプを追加で実装していきます。
走りジャンプの場合、どちらの足で踏み切るのか?というのが問題になります。
人間が実際に走る時は利き足というものがあって大体同じ足で踏み切りますが、ゲームの場合はスムーズさが求められるので現在の走りの姿勢に応じて踏み切りに適した足で踏み切るのが良いかと思います。
踏み切りたい足を判別するには、モーションが今どのような状況にあるのかを知る必要があります。
これにはAnimationEventというものを使います。
受け取り側のスクリプト
まず受け取り側のスクリプトを作ります。
内容はとりあえずこんな感じにしてみました。
public class PlayerFootParameters : MonoBehaviour
{
int currentFoot;
public int GetFoot()
{
return currentFoot;
}
public void SetFoot( int i )
{
currentFoot = i;
}
}
SetFoot()でAnimationEventからintの値で受け取り、他のスクリプトからはGetFoot()で今の状態が分かる内容にしてみました。
これは該当のAnimatorがついたゲームオブジェクトにアタッチしておきます。
AnimationEventの設定
FBXに含まれているアニメーションの場合、AnimationEventの設定箇所はFBXファイルを選択してAnimationタブの下の方で各Clipを選択した更に下の方にあります。
Events欄を開いて時間の左にあるボタンで追加することになりますが、これがものすごく見づらいです。

FBXの中のアニメーションクリップを選択してCtrl+Dでコピーしてから開くとAnimationのウインドウで編集できるようになります。コピーした方が操作しやすいです。

今回は、走りのモーションで右足で踏み切った方がいいタイミングになった箇所と左足で踏み切った方がいいタイミングになった箇所で2つのAnimationEventを作りました。
内容はこんな感じに設定します。

Functionは先ほど作ったスクリプト内の関数名のSetFootにします。Intの値にどちらの足なのかが分かるような値を入れます。
今回のスクリプトでは1の時に右足で-1の時に左足になるようにしようかなと思いました。値は自分が分かりやすいものでOKですが、適宜設定します。
あとはステートの設定でモーションを反転させることができるので、ステートを複製して左右で分岐するようにします。
スクリプトからの分岐方法はいろいろあると思いますが、僕はIntのパラメーターを追加して「0:その場」「1:走り右足」「-1:走り左足」になるようにし、2つのConditionsで分岐させる方法にしてみました。


こだわりたい場合
ここまででもまあまあ充分な仕上がりかなと思います。
ただし何度か試していて「足を逆向きに戻してジャンプする」という場合があって気になったので、僕はもう少し細かく区切ることにしました。
具体的には、踏み切りのモーションを「足を一番前に出している姿勢からジャンプ」「足をほぼ踏み切り状態にしている姿勢からジャンプ」で2つに分けて作ります。
更にAnimationEventを増やして4つにします。
パラメーターはそのままintで2と-2を使うようにするので、モーションさえ出来れば設定は簡単です。

踏み切り足を前に出している状態

ほぼ踏み切る寸前の状態
出来上がり
移動モーションが歩きの時はその場でジャンプ、走っている時は走りジャンプになります。遷移のタイミングもいろいろ調整してみました。
ちなみに全部終わるとこんな感じになっていると思います。まだ歩きとスニークとジャンプしかないのにグチャグチャです。

これはサブステートマシンというものを使うとこのくらいまでまとめられます。

サブステートマシンは単純にこの画面を見やすく管理する機能で、モーションの設定自体は変わらないので今回の記事では省略します。
気になる方は調べてみてください!