UnityのAnimatorでアニメーション遷移するときの自分なりの解

設計の指標なので、なんとなくUnityできる人向けな感じする

 

AnimatorController

アニメーションアセットを登録してトランジション作ったり、パラメータを色々持てる

 

Animatorの管理

アニメーションのトランジション制御をパラメータで行うのはトランジション設定を毎回やらないといけないし、矢印が量産されすぎてつらい

 

矢印量産をめんどくさがって減らすと、一回Exitを経由させてアニメーション遷移させたりしなければいけない

 

スクリプトでアニメーションの制御を行うと

スクリプト上で保存してるキャラクターの現在のStateと

アニメーションのパラメータがズレる自体が頻出して拡張性が低くなる

 

スクリプトを使わない(使えない)なら

トランジション制御をぽちぽち頑張って作るしかない

矢印の量産は必要経費として割り切る

 

スクリプトを使えるなら

AnimatorにStateを作って、State名をScriptableObjectに登録する

(Enumで定義して、Enum名をStateに合わせてもいい)

 

Animator.CrossFadeInFixedTime(StateName,duration);で制御すると良い

動的にトランジション制御を作成してくれるので、とても楽

ただ、レイヤー内を総当たりで検索してるらしいので、アニメーションの数が膨大になるとパフォーマンス的に厳しくなるのかも

ちなみにCrossFade(StateHash,duration);だとdurationが実時間分の遷移ではないので、意図した動作にならない

CrossfadeInFixedTimeおすすめ

 

EnumでState名を管理していた場合は

Animator.CrossFadeInFixedTime(Enum.State.ToString(),duration);

で矢印一個分の働きをしてくれる

 

制御の詰まりポイント

CrossFadeInFixedTimeのdurationが0よりも大きい時(主に3Dで、モーションブレンドさせたい時)

 

CrossFadeInFixedTimeを呼ぶと、前のStateからCrossFade先のStateに移動するまでにduration分の時間がかかる

 

CrossFade中は、Animatorから取得できるStateInfoは遷移が完全に終わらないと、遷移先のStateではなく、遷移前のStateのままになる

 

つまり

if(CurrentStateName == NextStateName) return;

みたいな形で

同じステートの時アニメーションが最初から再生される動作を弾くチェックしようとしても弾けない

他にも、遷移中に同じStateに遷移が行われてしまう要因にもなる

 

解決方法として、アニメーションの遷移を行った時は、コルーチンなりを使って

yield return new WaitForSeconds(duration);などアニメーション制御を待機させてあげると良いと思う

 

結果

Animatorぽちぽち地獄から解放されて、設定弄るだけでアニメーション制御の書き換えもできるようになる

今の所問題はないけどあったら追記予定

 

2016/8/25 追記

qiita.com

 

こんなものがあった。

併用してアニメーション遷移の汎用コンポーネント作りたい

 

2017/4月の追記

制御コンポーネントを作成して適用してみた(年明け前くらい)

いい感じだけど、NormalizedTimeが機能しなかったりして自前で実装した

 

f:id:yutakaseda3216:20170404113601p:plain

 

右側のPlayerStateTransitionはStateMachineBehaviour継承したクラスで

・Inputの入力受付時間

・ステートの自動終了時間

・ステートのキャンセル時間

・ステートのキャンセル先と優先度登録

 

とかできるようになってて、遷移先の切り替えが楽になった

やったね