今回はMecanim(Animator Controller)を使用している場合に即座にアニメーションが切り替わらない問題、その対策についてです。
例えば上の画像では、右はジャンプ開始時や着地直後に速やかにアニメーションが切り替わっているのに対して、左側はモーションの切替えが一瞬遅れているのが確認出来ます。この2D特有の現象の解決方法についてです。
2Dでアニメーションが即座に切り替わらない問題の解決法
アニメーションが即座に切り替わらない理由で真っ先に頭に上がるのはHas Exit Time
ですが、今回は残念ながら違います。
先に結論を言ってしまえば、これはTransitoin Duration(s)(日本表記:遷移間隔)
が0以外を設定しているために発生します。 なので、Transitoin Duration(s)
の値を0に設定する事で問題を回避することが出来ます。
原因
今回のケースの問題は、アニメーションが切り替わっているが、表示が切り替わっていない事が原因です。
通常アニメーションを切り替える場合、2つのアニメーションをブレンドする形で切り替えを行います。これを行わないと即座にポーズが差し替わってしまい、特に等身が高い場合は大きな違和感になります。このアニメーションのブレンド期間がTransition Duration(s)
です。
3Dの場合は結構有り難い機能ではありますが、2Dのスプライトアニメーションの場合はアニメーションのブレンドという物は存在しません。*1しかしてブレンド期間は用意されている訳で、結果としてブレンド期間がある場合、ブレンドが半分を超えるまで移行前のアニメーションが再生される事になります。
このブレンド期間を0にしてやることで、アニメーション切り替え後に即座に次のアニメーションを再生させます。これで2D アニメーションが遅延することは無くなります。
全てのTransition Durationを0にしたい
問題がわかった所で作業を行いたい所ですが、非常に面倒なことにTransition Durationは複数選択で一気に変更することが出来ません。また、初期設定では(たとえ2D設定であっても)Transition Duration
は0.25が初期値として設定されており、割と気づいたら紛れ込んでいるという事が多いです。さらにPresetを利用した初期値の設定も使用できないという、非常に面倒な項目でもあります。
なのでスクリプトで一気にTransition Durationを0にする方法を考えてみます。
以下のコードをEditorフォルダ以下に配置し、更新したいAnimatorController達を選択しつつAssets>UpdateTransitionTime
を実行します。これで全てのTransition Duration
は0になると思います。上手くいかない場合は頑張って改造して下さい。
関連
正直言ってしまえば、2Dの場合はAnimatorよりSimpleAnimatorのほうが管理が楽だし良いんじゃないかなと個人的には…
スケルタルアニメーションの場合、遷移時間は表現の上で非常に大事です。ただ遷移時間が長いとモッサリするのも事実
Transition Duration
が0なのに即座に切り替わらない場合は、HasExitTimeが怪しいです。それでも上手くいかない場合は、AnimatorControllerの動作を勘違いしているかもしれません。
コンポーネントやアセットの初期値をオーバーライドするPreset。今回の場合は「Transition先もオーバーライド」してしまうため使えませんが、他のアセット郡の初期値を考える場合には、非常に良い感じになります。
今回作成したコードのような処理は、AssetGraphToolで自動化出来ていると色々と楽で良いです。