Unityでキャラクタモーションをキー入力で切り替える方法

# はじめに
UnityにはHumanoidという、骨構造を人間として認識させる機能がある。キャラクタのskinデータ１つと、複数のモーションデータを使って、任意のキー入力で切り替える方法についてまとめた。

使用するデータはFBXフォーマットで、Mixamoを使って生成したものである。

なお、アクションゲームのような動きをさせたいのであれば、Mecanim, Third person assetなどを使ったほうがいいとおもうが、これらを使った方法は別稿にする。

# 環境
Unity 2021.3.10f1


# 下準備
mixamoで、passive_marker_manモデルを使い、以下のFBXデータを得る。
保存Formatは「FBX for Unity」とする。
| motion type | Skin |
|:-:|:-:|
| T-Pose  | With Skin |
| Standard Walk | Without Skin |
| Standard Run | Without Skin  |
| Run To Stop | Without Skin  |
| Right Turn | Without Skin  |
| Left Turn | Without Skin  |
| Idle | Without Skin  |


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/15bf4183-1726-696a-613e-d72ca8194bc2.png)
以下の操作をする。
・Unityのプロジェクトを作り、Assetsに適当なフォルダを作り、さきほどのFBXファイルをいれる。
・新たに、Animator ControllerをAssets内に作成し、ダブルクリックし、Animatorタブを表示する。（ファイル名は初期のままで進める）
・新規にPlaneを作成する。（必須ではない）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/cc617bd4-579b-dae7-c88d-07fb71a9c3b4.png)

asset内のT-Poseのモデルを選択し、RigタブAnimation TypeをHumanoidに変更し、Applyする。
同様の操作をすべてのFBXファイルについて、行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/9fe0e37f-c67e-faf8-9cf9-519037eab14f.png)
骨のデータ、アニメーションデータに加えて、Avatorが追加されているのを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/56b00f58-947a-c1be-5327-8d425d1108e3.png)

Skinの含まれるT-PoseのFBXファイルを選択し、MaterialsタブのExtract Texturesを選択し、FBXに埋め込まれているテクスチャを書き出す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/f76a0fe5-61de-284e-f1b2-575e75d027f1.png)

# Sceneへの配置
assetからSceneへT-Poseを配置する。
Hierarchy内のT-Poseのモデルを選択し、InspectorのAnimatorのControllerのボックスに、asset内に作成済みのAnimator ControllerをD&Dする。
Animatorウィンドウ内に、Without SkinのFBXデータ（idleなど）をD&Dする。（含まれるアニメションデータのみが入る）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/7b966bcf-1782-2c69-e09f-3f7eda52f376.png)

一旦、プロジェクトを再生して、モーションが適用されていることを確認する。
モーションさせ続けたいなら、該当データの「Loop Time」のチェックを入れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/35fe15a9-ad40-68fb-4db5-32e0093bc8d5.png)

# アニメーションの切り替え
キーボード入力でアニメーションを切り替える方法

Animatorウィンドウで以下の追加をする。
・Parametersタブの＋記号からintを選択し、motionという名前で追加する。
・本稿で最初に追加したAssetからidle, walk, run, rightTrun, leftTrunを追加する。
・idleに関しては、set as layer default stateに設定する。
・その他のモーションに関しては、Make Trasitionで矢印を図のようにつなぐ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/36016f19-3e3f-da67-86c7-ea5bff40d0c6.png)

モーションwalkへと繋がる矢印をクリックし、以下の設定をする。
・Has Exit Timeのチェックをオフにする。
・Conditionsにmotion, Equals, 1にする。
同様に、モーションrunに関して、以下の設定をする。
・Has Exit Timeのチェックをオフにする。
・Conditionsにmotion, Equals, 2にする。
以下同様に、
rightTrunでは、3
leftTurnでは、４
を設定する。
これで、プログラムのほうでmotionの値を変更すれば、アニメーションが切り替わる仕組みができた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/92223e9c-0434-8266-6451-a2cf26439dbc.png)

新規にC#のスクリプトを作成し(ファイル名はデフォルトのままとした)、Hierarchy内のキャラクタにD&Dで割り当てる。inspector内の一番下に追加されているのを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/924a8d46-14b9-f6ab-8b4d-9e0dba6b10a9.png)
ソースコードの例は以下。
asdfキーを押すと、motionの値が1,2,3,4になり、アニメーションが再生される。毎フレームmotionを0に戻しているが、アニメーションは１ループ再生されるようだ。

```cs:NewBehaviourScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    public Animator anim;

    // Start is called before the first frame update
    void Start()
    {
        anim = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        anim.SetInteger("motion", 0);//reset
        if (Input.GetKeyDown("a"))
        {
            anim.SetInteger("motion", 1);
        }
        if (Input.GetKeyDown("s"))
        {
            anim.SetInteger("motion", 2);
        }
        if (Input.GetKeyDown("d"))
        {
            anim.SetInteger("motion", 3);
        }
        if (Input.GetKeyDown("f"))
        {
            anim.SetInteger("motion", 4);
        }

    }
}

```

# BlendTreeで切り替える方法
検討中。