【Unity】キャラクターにSimpleAnimationでアニメーションをつける

追記

本記事は2023/09/16にUnityのバージョンを上げてリライトしています。

概要

以前の記事でキャラクターにキーボード操作で前進、後退、左右旋回とジャンプが行えるようにしました。

ただし、前回はアニメーションまでは付けていなかったので、動かしても味気ない感じです。そこで、今回はさらにキーボードで操作した際にキャラクターの体が動くようにアニメーションをつけていきたいと思います。

Animationの制御方法はAnimationControllerなどがありますが、今回は スクリプトで手っ取り早く制御できるSimpleAnimationを使用する方法 で行います。


環境

Unity Hub 3.5.0
Unity 2022.3.7f1

使用するキャラクタオブジェクト

前回に引き続いてSpace Robot Kyleを使用していきます。

https://assetstore.unity.com/packages/3d/characters/robots/space-robot-kyle-4696

Step1 : Animationの 入手

まずはキャラクターのRobotKyleを動かすためのAnimationClipを入手する必要があります。今回はAsset Storeから以下のStarter Assets – Third Persion Character ControllerのFree版を使用させてもらいました。

https://assetstore.unity.com/packages/essentials/starter-assets-third-person-character-controller-urp-196526

上記のリンク先からパッケージをダウンロードし、デフォルトのすべてがチェックが入った状態でパッケージを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のフォルダからドラッグ&ドロップで持ってくるだけ)


Step3 : Inspectorの設定

続いて、キャラクターのInspectorの設定を行っていきます。

SimpleAnimationスクリプトのアタッチ

Robot Kyleの[Inspector] > [Add Copmponent] > [Scripts]からImportしてきたSimpleAnimationComponentのなかのSimpleAnimations.csを追加します。

Rigの設定

RobotKyleモデルのRigからAnimatin TypeをHumanoidに設定します。これはThirdPersonControllerのAnimationを使用するためです。デフォルトでHumanoidになっているはずですが、一応確認しておきます。

Animatorの設定

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


SimpleAnimationの設定

次にSimpleAnimationで制御する項目と、ThirdPersonControllerのAnimationを対応付けていきます。Inspector内のSimpleAnimation(Script)を以下のように設定します。

  • 最初のAnimationの項目を選択し、ThirdPersonControllerのパッケージからIdleのAnimationを選択する
  • [+]ボタンでElementを追加し、Walk, Run, JumpStart, JumpLandを以下のように設定する

ThirdPersonControllerからIdleを選択する例

以上でInspectorの設定は完了です。

Step4 : Animationを制御するスクリプトの作成

まず、スクリプト全体としては以下のような形になります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // Start is called before the first frame update
    
    //接触ステータス初期化
    [SerializeField] public bool Grounded = true;

    //アニメーションステータス初期化
    [SerializeField] public bool Idling = true;
    [SerializeField] public bool Walking = false;
    [SerializeField] public bool Running = false;
    [SerializeField] public bool Jumping = false;
    [SerializeField] public bool Landing = false;
    [SerializeField] public bool InAnimation = false;

    //Rigidbody定義
    private Rigidbody _rb;

    //SimpleAnimation定義
    private SimpleAnimation _simpleAnimation;

    private string _currentState;

    //移動スピード定義
    private float speed = 6f;

    //ダッシュスピード定義
    private float sprintspeed = 9f;

    //方向転換速度定義
    private float angleSpeed = 200;

    //移動量変数定義(v:水平方向、h:垂直方向)
    private float v;
    private float h;

    void Start()
    {
        //Rigidbody componentを取得
        _rb = this.GetComponent<Rigidbody>();

        //キャラクタのSimpleAnimationを取得
        _simpleAnimation = this.GetComponent<SimpleAnimation>();

    }

    void Update()
    {
        // 地面接地時のみ移動とジャンプを許可
        if (Grounded) {
            //移動の実行
            Move();

            //ジャンプの実行
            Jump();
        }

        //Animationを実行
        AnimationPlay();
    }
    
    //地面(Groundタグ)に接触したときにはGroundedをtrue、Jumpingをfalseにする
    void OnCollisionEnter(Collision col)
    {
        if(col.gameObject.tag=="Ground")
        {
            //ジャンプ中だった場合はLandStateを実行
            if(Jumping)
                LandState();  
        }
    }

    //アニメーションイベント
    void OnFootstep() {
    }

    //アニメーションイベント
    void OnLand() {
        Grounded = true; //着地イベントが完了したら接地フラグを立てる
    }

    //動作用関数
    void Move() {
        //上下キーで通常移動、Shift+上下キーでダッシュ、それ以外は停止
        if (Input.GetKey(KeyCode.UpArrow) && Input.GetKey(KeyCode.LeftShift)){ //RUN
            v = Time.deltaTime * sprintspeed;
            RunState();
        }
        else if (Input.GetKey(KeyCode.UpArrow)){
            v = Time.deltaTime * speed; //walk
            WalkState();
        }
        else if (Input.GetKey(KeyCode.DownArrow)){
            v = -Time.deltaTime * speed; //walk back
            WalkState();
        }
        else {
            v = 0;
            IdleState();
        }
        
        //移動の実行
        if (!Jumping)//空中での移動は禁止
            transform.position += transform.forward * v;

        //左右キーで方向転換
        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);
    }

    //Jump用関数
    void Jump() {
        //スペースボタンでジャンプする
        if (Input.GetKey(KeyCode.Space))
        {
            //ジャンプさせるため上方向に力を発生
            _rb.AddForce(transform.up * 8, ForceMode.Impulse);
            //前後キーを押しながらジャンプしたときは前後方向の力も発生
            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);
            }
            JumpState();
        }
    }

    //アニメーション実行用関数
    void AnimationPlay(){
        if (Walking)
            _currentState = "Walk";
        else if (Running)
            _currentState = "Run";
        else if (Jumping)
            _currentState = "JumpStart";
        else if (Landing) 
            _currentState = "JumpLand";
        else
            _currentState = "Default";
        
        _simpleAnimation.CrossFade(_currentState, 0.1f);
    }

    //状態遷移用関数
    void JumpState() {
        Grounded = false;
        Idling = false;
        Running = false;
        Walking = false;
        Jumping = true;
        Landing = false;
    }
    void IdleState() {
        Idling = true;
        Running = false;
        Walking = false;
        Jumping = false;
        Landing = false;
    }
    void RunState() {
        Idling = false;
        Running = true;
        Walking = false;
        Jumping = false;
        Landing = false;
    }
    void WalkState() {
        Idling = false;
        Running = false;
        Walking = true;
        Jumping = false;
        Landing = false;
    }
    void LandState() {
        Idling = false;
        Running = false;
        Walking = false;
        Jumping = false;
        Landing = true;
    }
}

動かしてみると以下のような感じになります。

Walk

Run


JumpStart

JumpLand


まとめ

今回はRobotKyleの動作にアニメーションをつける方法について紹介しました。次回はさらにRobotyKyleにソードを持たせて攻撃する動きを実現したいと思います。

以上

Unityを一から学ぶのにおすすめの本はコチラ

おすすめ

3件のフィードバック

  1. 2020年10月9日

    […] 前回はRobot Kyleにキーボードで基本動作ができるようにしましたが、今回はRobotKyleに武器(レーザーソード)を持たせたいと思います。 […]

  2. 2020年11月1日

    […] […]

  3. 2020年12月15日

    […] 【Unity】キャラクターにSimpleAnimationでアニメーションをつける […]

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です