【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版を使用させてもらいました。
上記のリンク先からパッケージをダウンロードし、デフォルトのすべてがチェックが入った状態でパッケージを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件のフィードバック
[…] 前回はRobot Kyleにキーボードで基本動作ができるようにしましたが、今回はRobotKyleに武器(レーザーソード)を持たせたいと思います。 […]
[…] […]
[…] 【Unity】キャラクターにSimpleAnimationでアニメーションをつける […]