わたくしの場合はCharacterControllerやRigidbody+コライダを用いたキャラクターの移動を行ってきました。
CharacterControllerの場合は
Rigidbody+コライダの場合は
です。
この場合はキャラクターを移動させる為にスクリプトを作成し前方に歩かせたり、重力を計算したりする必要がありました。
しかしスクリプトでキャラクターの移動をさせるのではなく、元々のアニメーションの動きでキャラクターを移動させたり敵を攻撃させる方法もあります。
こちらの方法であれば元々のアニメーションの動きでキャラクターの動作をさせる事が出来、制御も楽になるかも?しれません。
アニメーションの動きだけで動かすキャラクターは
上のような感じになります。
キャラクターの準備
キャラクターはAssets/Standard Assets/Characters/ThirdPersonCharacter/Modelsの中にあるEthanを使います。
ヒエラルキー上にEthanをドラッグ&ドロップしておきます。
キャラクターのコライダと接地の判断
キャラクターの動きはアニメーションで行いますが、キャラクターの当たり判定や地面と接地しているかどうかはCharacterControllerコンポーネントを使って行います。
CharacterControllerを使うと階段等の段差があるところも歩けるので便利です。
ヒエラルキー上のEthanを選択し、インスペクタのAdd ComponentからPhysics→CharacterControllerを取り付けます。
Animator Controllerの作成
次はEthanに設定するAnimator Controllerの作成をします。
Assetsエリア内で右クリックからCreate→Animator Controllerを選択します。
アニメーションパラメータ―にFloat型のForwardSpeedとLateralSpeed、Trigger型のJumpを作成します。
FowardSpeedには前後の数値をスクリプトから設定、LateralSpeedは左右の数値をスクリプトから設定、Jumpはスクリプトでジャンプキーを押した時にトリガーします。
アニメーションの遷移は以下のように作成します。
アニメーターコントローラーの詳細は
等を参照してください。
Idleはその場で立っているアニメーション(スタンダードアセットのHumanoidIdleを設定)
WalkForwardは前方に歩くアニメーション(スタンダードアセットのHumanoidWalkを設定)
BackStepは後方にバックステップするアニメーション(後ろ歩きのアニメーションなどを設定してください)
WalkRightは右に回転するアニメーション(スタンダードアセットのStandHalfTurnRightを設定)
WalkLeftは左に回転するアニメーション(スタンダードアセットのStandHalfTurnLeftを設定)
Jumpは真上にジャンプするアニメーション(ジャンプするアニメーションなどを設定してください)
ジャンプアニメーションは
上のようにキャラクターの土台を上下させるように作成します。
アニメーションを選択し、インスペクタでルートモーションの設定をします。
Root Transform Position(Y)のチェックを外しジャンプアニメーションの動きがTransformに影響するようにします。
ルートモーションに関しては
を参照してください。
アニメーションの遷移条件は
Idle→WalkForwardはForwardSpeedがGreaterで0.1でHas Exit Timeのチェックを外し
WalkForward→IdleはForwardSpeedがLessで0.1でHas Exit Timeのチェックを外し
Idle→BackStepはForwardSpeedがLessで-0.1でHas Exit Timeのチェックを外し
BackStep→IdleはHas Exit Timeにチェックを入れる
Idle→WalkRightはLateralSpeedがGreaterで0.1でHas Exit Timeのチェックを外し
WalkRight→IdleはLateralSpeedがLessで0.1でHas Exit Timeのチェックを外し
Idle→WalkLeftはLatelalSpeedがLessで-0.1でHas Exit Timeのチェックを外し
WalkLeft→IdleはGreaterで-0.1でHas Exit Timeのチェックを外し
それぞれの状態→JumpはJumpがトリガーされた時でHas Exit Timeのチェックを外し
Jump→IdleはHas Exit Timeにチェックを入れる
になります。
BackStepとJumpはアニメーションが終了したらIdleに戻るようにしています。
アニメーターコントローラーが出来たので、EthanのAnimatorコンポーネントのControllerに今作成したAnimator Controllerを設定します。
アニメーションの動きを移動値に加える為Apply Root Motionにチェックを入れておきます。
キャラクター移動スクリプトの作成
キャラクターの動きはアニメーションでのみ動かしますがAnimator Controllerのアニメーションパラメータ―を操作する必要があるので、それを操作する処理をスクリプトで作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class AnimationMove : MonoBehaviour { private CharacterController characterController; private Animator animator; // Start is called before the first frame update void Start() { characterController = GetComponent<CharacterController>(); animator = GetComponent<Animator>(); } // Update is called once per frame void Update() { if (characterController.isGrounded) { // 左右前方の入力値をアニメーションパラメータ―に渡す animator.SetFloat("ForwardSpeed", Input.GetAxis("Vertical")); animator.SetFloat("LateralSpeed", Input.GetAxis("Horizontal")); if (Input.GetButtonDown("Jump")) { animator.SetTrigger("Jump"); } } } } |
UpdateメソッドでCharacterControllerのisGroundedを使って地面と接地しているか確認し接地している時だけ移動とジャンプが出来るようにします。
移動に関してはInput.GetAxisを使って前後左右の移動値をそのままアニメーションパラメータ―のForwardSpeedとLateralSpeedに渡すだけです。
ジャンプキーが押された時はアニメーションパラメータ―のJumpをトリガーします。
キャラクターの移動をスクリプトで操作する必要がないのでかなりシンプルなスクリプトですね。
Ethanのインスペクタは
上のようになります。
これで機能が出来ました。
試すと記事の最初に示したようにアニメーションの動きだけでキャラクターが動くようになります。
重力に関して
Apply Root Motionにチェックを入れているとアニメーションの動きに応じて重力が勝手に働いてくれるようですが、アニメーションクリップのルートモーションのRoot Transform Position(Y)のチェックが外されていると重力が働かないようです。
Root Transform Position(Y)にチェックが入っているとAnimatorのgravityWeightが1となりアニメーションに基づく重力が働き、チェックがされていない場合はgravityWeightが0で重力がまったく働きません。
今回のアニメーターコントローラーで設定しているアニメーションクリップではジャンプとバックステップのRoot Transform Position(Y)のチェックを外しているのでその状態だと重力が働かないですが、Has Exit Timeの条件で必ずIdleに状態が移動するのでこれは問題なさそうです。
ただ最初のサンプル動画で階段上でバックステップをした時にわかると思いますが、バックステップ中は重力が働きません。
それ以外のアニメーションクリップはスタンダードアセットのもので全てRoot Transform Position(Y)にチェックが入っている為、問題はなさそうです。
それ以外の問題として落下時間が長くなると急に重力加速度が低下して落下速度が落ちます。
RigidbodyのUse Gravityにチェックを入れたゲームオブジェクトと比較して試しましたが、途中まではほとんど変わらないですが途中でガクンと落下速度が落ちました。
ここら辺の理由はちょっとわかりません。
そんなに長い間落下させるゲームじゃなければ問題ないかなぁ・・・・ボソッ
終わりに
以前からずっとキャラクターの操作でAnimatorのApply Root Motionのチェックを外した方法で行ってきました。
ですがアニメーションの動きをそのまま反映させたい場合はApply Root Motionのチェックを入れて操作するとスクリプトで移動処理を記述する必要がないので便利ですね。