江上宿六です。
歩きモーションで足が変になっているのを確認しましたけども、気にせずに。
ともかく自分好みにアニメーションを遷移させて再生できるようになったハズです。
色々な状況に対応したAnimatorControllerを作ってみましょう。
こんな感じのものが出来上がりましたが、なんか見た感じヤバい気がします。
恐らくフラグの管理などが正しく設定されれば正しく動く物だとは思いますけど
今後もっとアニメーションが増えたりする事を考えるともう少しスッキリさせたいと
思いますよね、という所で使えそうなのがAnyStateとExitです。
AnyStateから矢印を伸ばすと、現在がいかなるState上であれ指定のStateへと
移動することが出来るようになるのだと思います。
今回は全てのStateが他の全てのStateに移動出来るのでこんな感じでしょうか。
それぞれの矢印に条件が追加されています。 実際にやる場合は優先度に応じた
順番とかにしておけば分かり易いかもしれないですね。 ですがこれだけだと
Idleに戻る事が出来ませんが、そういう時の為にExitがあります。
Exitは初期状態ではだいぶ右の方にあって、レイアウトや解像度なんかの関係で
なかなか見えない事があったりしますが、ちゃんと存在しています。
Exitに辿り着くとEntryに向かうので結果Idleに戻るという流れになります。
それぞれのStateから矢印を伸ばしてExitへ向かう条件を設定しましょう。
スクリプトはとりあえずこんな感じですね。 上矢印で移動状態になり、
Shiftが押されていたら走り、押されてなければ歩く。 上矢印を離せば止まる。
恐らくこれで想定している動きが出来ると思うので実行してみましょう。
歩くように操作したのですが、なんかガタガタしていてちゃんと歩けていません。
こうなってしまった原因なのですが、AnyStateを使うとWalkにいながらWalkへと
遷移してしまうなんて事が起きてしまい、それによってWalkの最初の方が連続して
再生されてしまっているわけです。 これはなんとかしましょう。
AnyStateからWalkに向かう矢印を選択し、InspectorのSettings内にある
CanTransitionToSelfにチェックが入っているか確認します。 入っている場合は
上記のようになってしまうので、今回はチェックを外しておきましょう。
他のStateに対しての矢印も必要であれば同様に設定しておきましょう。
歩いたり走ったりするのは多分なんとかなりました。
次は攻撃モーションの方に手を付けてみましょう。
なんの変哲も無いスクリプトを書いてみました。 実行して動作を確認しましょう。
Zキーでフラグが立ち、攻撃のアニメーションが再生されたのは良いのですが、
falseになる事がなく、この状態を保持してしまっています。 これは駄目ですね。
こういう状態を解消する為に一手間加えてみます。
AnimatorのGetCurrentAnimatorStateInfo(0).normalizedTimeというのを判定します。
これは現在のStateに切り替わってからの時間を表すのではなく、再生されている
アニメーションが何回分呼び出されているかというのを表しているようです。
この値が1.0fになった時がアニメーションが1回行われたと判断できます、多分。
なので、その時にフラグを消してやれば良いでしょう。
これで概ね良い感じではありますが、まだ少し問題が残っています。
処理順の問題なんですが、この判定は他のStateに移行する前が行われるので、
攻撃のフラグを立ててもIdleやWalk等が1回再生された状態だと遷移する前に
フラグが消されてしまうので、現在のStateを確認してから判定を行うようにします。
GetCurrentAnimatorStateInfo(0).IsName("")で現在のState名を判定出来ます。
今回は"Sword1"の時に真になり、加えてアニメーションが1回行われたときに
isAttackフラグがfalseになるという感じです。
こんな感じですね。 個人的な操作感では特におかしい所は無かったと思います。
キャラが回転しているのは仕様です。 モデルの回転情報がそのまま使われて云々。
どうにかしてカッチリした制御を実現したかったんですが、現状はこんな感じです。
normalizedTimeに辿り着く前はHasExitTimeを使って空のStateに移動させてから
フラグを消し、Exitに向かわせるなんて事をしていたら空のStateから即座に移動が
出来ず空のアニメーションが再生されたりと、なかなか試行錯誤をしてました。
次回もアニメーション関連の事です。 制御というよりは管理ですかね。