Unity

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

投稿日:2020年10月3日 更新日:

概要

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

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

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版を使用させてもらいました。

https://assetstore.unity.com/packages/tools/utilities/third-person-controller-basic-locomotion-free-82048

上記のリンク先からパッケージをダウンロードし、デフォルトのすべてがチェックが入った状態でパッケージを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にソードを持たせて攻撃する動きを実現したいと思います。

以上

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

-Unity

執筆者:


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

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

comment

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

関連記事

【Unity】キャラクターが近づいたら自動ドアが開閉するようにする

Contents1 概要1.1 実現例2 使用アセット3 Step 1 : Doorオブジェクトの配置4 Step2 : Colliderの設定5 Step3 : アニメーションとスクリプト 概要 U …

【Unity】キャラクター操作その4 –  レーザーソードを持たせてON/OFFする

Contents1 概要2 環境3 Step1 : レーザーソードの調達4 Step2 : レーザーソードを持たせる5 Step3 : レーザーソードをON/OFFする6 まとめ 概要 前回はRobo …

【Unity】一定範囲に入ると追ってくるスクリプト

Contents1 目的2 環境3 完成系4 Step1 : プレイヤーの配置5 Step:2 追いかけてくるオブジェクトの配置6 Step : 3 スクリプトの作成7 Step : 4 動作確認 目 …

【Unity】キャラクター操作 – ジャンプ時にカメラの向きを変える

Contents1 概要2 完成イメージ2.1 Before2.2 After3 カメラの制御方法3.1 カメラオブジェクトの初期姿勢の取得3.2 小刻みに目標角度まで制御3.3 初期姿勢に戻す 概要 …

【Unity】オブジェクトを周回させるスクリプト

Contents1 目的2 環境3 Step1 : 必要AssetのDownload&Import4 Step2 : オブジェクトの配置5 Step3 : 周回スクリプトの作成6 Step4 …

言語切り替え

カテゴリー