Mesh Animatorでつまづいたポイント

上記のツイートのようにMesh Animator最高なのですが、バグなのか仕様なのかわからないつまづきポイントがあったので記載しておきます。

 

Mesh Animatorで動かせるオブジェクトを用意した状態から説明を開始します。

 

今回はゲーム開始時に「Attack」アニメーションが再生されるようになっており、

2秒後に「Shield」アニメーションが再生されるようになっています。

どちらのアニメーションもループしない設定です。

 

「Shield」アニメーション再生後、現在どのアニメーションが再生されているかデバッグログに表示し、「Shield」アニメーションに設定してあるイベントが呼び出されたときに「何フレーム目に設定したイベントで、ゲーム開始から何秒後に呼び出されたか」表示しています。

アニメーション再生用のスクリプト

Shieldアニメーションのインスペクター

この状態でゲームを開始すると「Attack」アニメーションが再生され、再生が終わると終わった時点のフレームで停止します。

インスペクター上の「Current Frame」も43で停止しています。

Attackアニメーションの再生が終わりアニメーションが停止

そしてゲーム開始から2秒後、「Shield」アニメーションが再生されるのですが、ここで問題が発生します。

なんと18フレーム目から再生されてしまいます。

「Attack」アニメーションが1.4秒なので、停止してからの待ち時間は0.6秒。

どちらのアニメーションも30フレームで1秒なので、0.6秒=18フレーム。

そう、停止してからの待ち時間で経過した時間分、次のアニメーションが進んだ状態で再生されてしまうのです。

(待ち時間が次のアニメーション再生時間より長い場合は、最終フレームが再生されます)

 

さらに問題はもう一つ。

1フレーム目に呼び出すはずのイベントが呼ばれているのです。

これは怖い。

アニメーションが切り替わっていない・再生されていないように見えるのにイベントだけ呼ばれている、なんてことも起こりうるわけです。

18フレームから再生されてしまう

これを回避する方法が2つ見つかりました。

①アニメーション停止後に待ち時間があるアニメーションは、ループ設定にしておく

 これをすると次のアニメーションが0フレームから再生されるので問題は起こりません。

 ループ用のアニメーションを用意して設定するのがめんどくさいですが。

 

②MeshAnimatorBase.RestartAnim();を使う

 これは現在再生中のアニメーションを最初から再生するというメソッドです。

 次のアニメーションを再生した直後にRestartAnim();を行うとループ設定がなくても正常に次のアニメーションが再生され、イベントも正常に動作しました。

 手間がかからない分こちらの方が楽ですね。

Shieldアニメーション再生後にRestartAnim();を行う

他にも何かつまづくポイントがあったら記載したいと思います。