今回はUnityでアニメーションを操作、制御する事をやってみたいと思います。
Unityではアニメーションの状態と遷移とその条件をAnimatorControllerで作成し、遷移条件をスクリプトから操作してキャラクター等のアニメーションを変化させます。
前回までで、キャラクターの設置と簡単な移動スクリプトの作成までが終わりました。
前回までに作った「masasi」君を使おうと思ってた方は、やり直しから始まります。ごめんなさい。
まずは「masasi」君の原形Army01のプレハブを選択してください。
上画面のように、インスペクタ上でRigを選択しAnimation TypeをHumanoidに変更します。
Humanoidに変更すると、他の人型キャラクターで使用していたアニメーションを、このキャラクターでも使用する事が出来ます。
その為、アニメーションだけ別に作成しておけばAnimation TypeがHumanoidのキャラクターに他の人型キャラクター用に作成したアニメーションを適用出来ます(リターゲット機能)。
「masasi」君の再設置が終わったら、CharacterControllerの取り付けとスクリプトMoveを設定しパラメータを入れておきます。
さて、ここまでが前回までにやるべきだった事への修正で、これからが今回やりたかった事です。
Animator Controllerの作成
ProjectウインドウのAssetsフォルダで、アニメーションをコントロールするアニメーターコントローラーを作成します。
上画面のように右クリック→Create→Animator Controller
を選択します。
できたら、名前を「masasi」としておきます。
これは、「masasi」君に使用するアニメーターコントローラーだとわかりやすくする為で、他の名前にしてもかまいません。
Animator Controllerのmasasiを、「masasi」君のコンポーネント上のAnimatorにドラッグ&ドロップします。
これで、今作成したmasasiという名前のアニメーターコントローラーで「masasi」君のアニメーションを制御する事が出来ます。
アニメーターコントローラの状態と遷移を作成する
Animator Controllerの中を見てみます。
masasiアニメーターコントローラーをダブルクリックします。
上画面のようにAnimatorタブが開くので、
右クリック→Create State→Empty
を選択します。(下画面)
これで、一つのアニメーションの状態が作成されました。
下画面のように、インスペクタ上で名前をIdleに変更し、Motionの右の丸部分をクリックしHumanoid Idleを選択します。
今回はキャラクターがその場に立っているアニメーションの状態にIdleという名前を付けましたが、自分でわかりやすい名前を付けてください。
これで、Idleの状態の時はHumanoid Idleのアニメーションが再生されます。
このHumanoid Idleは、スタンダードアセットに入っているThird Person Controllerで使っていたアニメーションで、それをそのまま「masasi」君に適用しました。
(赤丸部分を参考にしてください)
これでIdle、つまり何もしてないボーっと突っ立っている状態を作成しました。
Entryから繋がっているのが初期状態になります。
これで「masasi」君が登場すると同時にIdle状態になるはずです。
Unityの実行ボタンを押して確認してみましょう。
「masasi」君がゆらゆら揺れながら立っている状態になります。
次に歩く状態を作成します。
上画面のようにWalkという状態を作り、Idleの時と同じように設定します。(赤丸を参考に)
次に、Idle状態からWalk状態、Walk状態からIdle状態への遷移を作成します。
状態を選択して、右クリック→Make Transitionでその状態から別の状態への遷移の矢印が出るので、Walk状態をクリックします。
Idle→Walk、 Walk→Idle
という双方向の遷移が出来たら、次はその遷移条件を作成します。
アニメーションパラメータを作成し遷移する条件を指定する
上画面の赤丸部分のParametersを選択し、少し下にある+をクリックして、Floatを選択します。
IdleからWalkに遷移する時には、Floatの値(小数点込みの値)で遷移させたい為です。
名前はSpeedとしておきます。
Animator Controllerの遷移のための条件変数Speedが出来ましたので、
Idle→Walkへの遷移条件にSpeedの条件を入れます。
上画面のように、赤い四角部分をクリックし条件Speedを加えます。
Speedが0.1を超えたらIdleからWalkに遷移、Speedが0.1より下になったらWalkからIdleへと遷移するように設定します。
Idle→Walkの時はConditionsでSpeedを設定したら、Greaterにして値に0.1、
Walk→Idleの時はConditionsでSpeedを設定し、Lessにして値に0.1を設定します。
これで遷移とその条件の作成が終わりましたので、スクリプトからその条件値を変更してみます。
アニメーションパラメータをスクリプトから変更
スクリプトからAnimatorControllerのアニメーションパラメータであるSpeedの値を変更します。
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 33 34 35 | using UnityEngine; using System.Collections; public class Move : MonoBehaviour { private CharacterController characterController; private Vector3 velocity; [SerializeField] private float walkSpeed; private Animator animator; // Use this for initialization void Start () { characterController = GetComponent <CharacterController> (); animator = GetComponent <Animator> (); } // Update is called once per frame void Update () { if(characterController.isGrounded) { velocity = new Vector3 (Input.GetAxis ("Horizontal"), 0f, Input.GetAxis ("Vertical")); if(velocity.magnitude > 0.1f){ animator.SetFloat("Speed", velocity.magnitude); transform.LookAt(transform.position + velocity); } else { animator.SetFloat("Speed", 0f); } } velocity.y += Physics.gravity.y * Time.deltaTime; characterController.Move(velocity * walkSpeed * Time.deltaTime); } } |
フィールドにAnimator型のanimatorを宣言し、Startメソッドで自身に設定されているAnimatorコンポーネントを取得します。
animator値の操作の所を見ていきます。
velocity.magnitudeはベクトルの長さを表わしていて、この場合は方向キーの押した向きの長さ(0~1.5?)で表されます。
これが0.1より大きくなった場合に、animator.SetFloat(“Speed”, velocity.magunitude)で、先ほど作ってAnimatorコンポーネントに設定したAnimator Controller(masasi)のアニメーションパラメータのSpeedの値を設定しています。
ここで、Speedの値が0.1より大きい値が設定されるので、アニメーションのWalkが再生されることになります。
0.1より小さい場合は0をセットし、Idleが再生されるようにしています。
キャラクターの向きの変更と向いている方向への移動
アニメーションの再生がきちんとされるようになったので、キャラクターの向きも押した方向を見るようにします。
transform.LookAt(transform.position + velocity);
transform.LookAtで向きを変更出来ます。
transform.positionがMoveスクリプトが設定されている「masasi」君の位置で、velocityがキーを押している方向の値なので、足した場合は
masasiのいる位置 + 押した方向のベクトル
となります。
つまりそこにLookAtする事によってその方向をキャラクターが向くようになります。
ついでに、インスペクタのAnimatorコンポーネントのApply Root Motionのチェックを外しておいてください。
これをチェックしていると、アニメーションの動きがキャラクターの移動に反映されてしまいます。(キャラクターの移動や角度にアニメーションの変更値が反映されてしまいます)
アニメーションはその場で動作だけをさせ、スクリプトで移動させたいのでチェックを外します。
終わりに
これでキャラクターが地面の上を移動する事が出来るようになりました!
いやぁUnityすごいですねぇ・・・。
次回はカメラの調整等をしてみようかと思います。