Contents
概要
以前の記事でキャラクターにキーボード操作で前進、後退、左右旋回とジャンプが行えるようにしました。
ただし、前回はアニメーションまでは付けていなかったので、動かしても味気ない感じです。そこで、今回はさらにキーボードで操作した際にキャラクターの体が動くようにアニメーションをつけていきたいと思います。
Animationの制御方法はAnimationControllerなどがありますが、今回は スクリプトで手っ取り早く制御できるSimpleAnimationを使用する方法 で行います。
環境
Windows10
Unity 2020.1.f1
使用するキャラクタオブジェクト
前回に引き続いてSpace Robot Kyleを使用していきます。
https://assetstore.unity.com/packages/3d/characters/robots/space-robot-kyle-4696
Step1 : Animationの 入手
まずはキャラクターのRobotKyleを動かすためのAnimationClipを入手する必要があります。今回はAsset Storeから以下のThird Persion ControllerのFree版を使用させてもらいました。
上記のリンク先からパッケージをダウンロードし、デフォルトのすべてがチェックが入った状態でパッケージをUnityのProjectへインポートします。

Step2 : SimpleAnimationの取得
Animationの制御として、UnityではコーディングレスなAnimationControllerを使用することができますが、AnimationControllerはシンプルなAnimationの遷移の場合は非常に分かりやすいのですが、使用するクリップの数や遷移の数が多くなってくると、管理が難しくなってくる傾向にあると思います。
そこで今回はスクリプトベースでAnimationの制御を管理できるアセットであるSimpleAnimationを使用してしていきたいと思います。
https://github.com/Unity-Technologies/SimpleAnimation
MIT License
Copyright (c) 2017 Unity Technologies
https://github.com/Unity-Technologies/SimpleAnimation/blob/master/LICENSE
上記からSimpleAnimationをダウンロードし、その中のSimpleAnimationComponentをUnity Projectにインポートします。(Windowsのフォルダからドラッグ&ドロップで持ってくるだけ)

次にImportしてきたSimpleAnimationComponentのなかのSimpleAnimations.csをキャラクターオブジェクトへアタッチします。

Step3 : Inspectorの設定
続いて、キャラクターのInspectorの設定を行っていきます。
Rigの設定
RobotKyleモデルのRigからAnimatin TypeをHumanoidに設定します。これはThirdPersonControllerのAnimationを使用するためです。

設定したら忘れずにApplyを押します。
Animatorの設定
次にAnimatorの設定を行います。AvatarでRobot KyleAvatorを選択します。また、 Apply Root Motionのチェックは外しておきます。 これはAnimation再生時の移動をアニメーション由来の動作ではなく、スクリプトで制御したいためです。

SimpleAnimationの設定
次にSimpleAnimationで制御する項目と、ThirdPersonControllerのAnimationを対応付けていきます。Inspector内のSimpleAnimation(Script)を以下のように設定します。
- 最初のAnimationの項目を選択し、ThirdPersonControllerのパッケージからIdleのAnimationを選択する
- Sizeを”4″に変更し、Element1からElement3に対してRun、Sprint、Jumpを同様に設定する

ThirdPersonControllerからIdleを選択する例

以上でInspectorの設定は完了です。
Step4 : Animationを制御するスクリプトの作成
まず、スクリプト全体としては以下のような形になります。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerConTest : MonoBehaviour { // Start is called before the first frame update //キャラクターの操作状態を管理するフラグ [SerializeField] public bool onGround = true; [SerializeField] public bool inJumping = false; //rigidbodyオブジェクト格納用変数 Rigidbody rb; //移動速度の定義 float speed = 6f; //ダッシュ速度の定義 float sprintspeed = 9f; //方向転換速度の定義 float angleSpeed = 200; //移動の係数格納用変数 float v; float h; //SimpleAnimation変数 SimpleAnimation simpleAnimation; void Start() { //キャラクタのrigidbodyの取得 rb = this.GetComponent<Rigidbody>(); //キャラクタが回転してしまわないように回転方向を固定する rb.constraints = RigidbodyConstraints.FreezeRotation; //キャラクタのSimpleAnimationを取得 simpleAnimation = this.GetComponent<SimpleAnimation>(); } // Update is called once per frame void Update() { //Shift+上下キーでダッシュ、上下キーで通常移動,それ以外は停止 if (Input.GetKey(KeyCode.UpArrow) && Input.GetKey(KeyCode.LeftShift)) v = Time.deltaTime * sprintspeed; else if (Input.GetKey(KeyCode.DownArrow) && Input.GetKey(KeyCode.LeftShift)) v = -Time.deltaTime * sprintspeed; else if (Input.GetKey(KeyCode.UpArrow)) v = Time.deltaTime * speed; else if (Input.GetKey(KeyCode.DownArrow)) v = -Time.deltaTime * speed; else v = 0; //移動の実行 if (!inJumping)//空中での移動を禁止 { transform.position += transform.forward * v; } //スペースボタンでジャンプする if (onGround) { if (Input.GetKey(KeyCode.Space)) { //ジャンプさせるため上方向に力を発生 rb.AddForce(transform.up * 8, ForceMode.Impulse); //ジャンプ中は地面との接触判定をfalseにする onGround = false; inJumping = true; //前後キーを押しながらジャンプしたときは前後方向の力も発生 if (Input.GetKey(KeyCode.UpArrow)) { rb.AddForce(transform.forward * 6f,ForceMode.Impulse); } else if (Input.GetKey(KeyCode.DownArrow)) { rb.AddForce(transform.forward * -3f, ForceMode.Impulse); } } } //左右キーで方向転換 if (Input.GetKey(KeyCode.RightArrow)) h = Time.deltaTime * angleSpeed; else if (Input.GetKey(KeyCode.LeftArrow)) h = -Time.deltaTime * angleSpeed; else h = 0; //方向転換動作の実行 transform.Rotate(Vector3.up * h); //前後方向キーを押したとき if (Input.GetKey(KeyCode.UpArrow)|| Input.GetKey(KeyCode.DownArrow)) { //ジャンプ中のとき if (inJumping) { //ジャンプアニメーションを再生 simpleAnimation.CrossFade("Jump", 0.1f); } //ダッシュキー押下時 else if (Input.GetKey(KeyCode.LeftShift)) //ダッシュアニメーションを再生 simpleAnimation.CrossFade("Sprint", 0.1f); else { //ジャンプ中 if (inJumping) //ジャンプアニメーションを再生 simpleAnimation.CrossFade("Jump", 0.1f); else //移動アニメーションを再生 simpleAnimation.CrossFade("Run", 0.1f); } } //スペースキー押下時 else if (Input.GetKey(KeyCode.Space)) { //ジャンプアニメーションを再生 simpleAnimation.CrossFade("Jump", 0.1f); inJumping = true; } else//それ以外 { if (inJumping) { }//ジャンプ中はそのまま else//それ以外 { //デフォルトアニメーションを再生 simpleAnimation.Play("Default"); } } } //地面に接触したときにはonGroundをtrue、injumpingをfalseにする void OnCollisionEnter(Collision col) { if (col.gameObject.tag == "Ground") { onGround = true; inJumping = false; simpleAnimation.Stop("Jump"); simpleAnimation.Play("Default"); } } }
それでは、それぞれの部分でやっていることを解説していきます。
SimpleAnimationの定義
変数定義部
SimpleAnimationComponentを格納するための箱を用意します。
SimpleAnimation simpleAnimation;
void Start部
キャラクタに取り付けたSimpleAnimationのスクリプトで定義されたSimpleAnimationComponentを最初に取得しておきます。
//キャラクタのSimpleAnimationを取得 simpleAnimation = this.GetComponent<SimpleAnimation>();
Jump、Run、Sprintのアニメーション制御
- 上下キー+スペースキーでJumpアニメーション実行
- 上下キー+左シフトキーでSprintアニメーション実行
- Jump中でない場合に上下キーでRunアニメーション実行
- スペースキーでJumpAnimation実行
- その他はDefault(Idle)アニメーション実行
//前後方向キーを押したとき if (Input.GetKey(KeyCode.UpArrow)|| Input.GetKey(KeyCode.DownArrow)) { //ジャンプ中のとき if (inJumping) { //ジャンプアニメーションを再生 simpleAnimation.CrossFade("Jump", 0.1f); } //ダッシュキー押下時 else if (Input.GetKey(KeyCode.LeftShift)) //ダッシュアニメーションを再生 simpleAnimation.CrossFade("Sprint", 0.1f); else { //ジャンプ中 if (inJumping) //ジャンプアニメーションを再生 simpleAnimation.CrossFade("Jump", 0.1f); else //移動アニメーションを再生 simpleAnimation.CrossFade("Run", 0.1f); } } //スペースキー押下時 else if (Input.GetKey(KeyCode.Space)) { //ジャンプアニメーションを再生 simpleAnimation.CrossFade("Jump", 0.1f); inJumping = true; } else//それ以外 { if (inJumping) { }//ジャンプ中はそのまま else//それ以外 { //デフォルトアニメーションを再生 simpleAnimation.Play("Default"); } }
地面接地時の制御
- Groudに接触したらJumpアニメーションを停止し、Default(Idle)アニメーションを実行
void OnCollisionEnter(Collision col) { if (col.gameObject.tag == "Ground") { onGround = true; inJumping = false; simpleAnimation.Stop("Jump"); simpleAnimation.Play("Default"); } }
動かしてみると以下のような感じになります。
Run

Sprint

Jump

まとめ
今回はRobotKyleの動作にアニメーションをつける方法について紹介しました。次回はさらにRobotyKyleにソードを持たせて攻撃する動きを実現したいと思います。
[…] 前回はRobot Kyleにキーボードで基本動作ができるようにしましたが、今回はRobotKyleに武器(レーザーソード)を持たせたいと思います。 […]
[…] […]
[…] 【Unity】キャラクターにSimpleAnimationでアニメーションをつける […]