[Unity]アニメーション関連まとめ

## 概要
調べてわかったことをまとめた。

例として登場するスクリーンショットは無料Assetである「3rd Person Controller + Fly Mode」から拝借させていただいている。


## Animatorコンポーネント
ゲームオブジェクトにアニメーションを追加するコンポーネント。
当該コンポーネントのアタッチにあたっては、適用する「AnimatorController」を設定する必要がある。

例. 「CharacterCotroller」というAnimatorControllerが設定されているAnimatorコンポーネント
![スクリーンショット 2021-01-31 13.49.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/2706f5f6-6b48-62c7-0294-89ed38d44549.png)


## AnimatorController
複数の「アニメーションクリップ」を管理し、どの条件でどのアニメーションクリップを対象ゲームオブジェクトに対して適用するか・組み合わせるかを制御する設定ファイルである。

内容として大きくは、以下2つで構成される。

- パラメータ定義(「状態遷移の条件」や「アニメーションのブレンドの設定」に使う)
- ステートマシン(状態遷移)

### パラメータ定義

例. 
![スクリーンショット 2021-01-31 13.48.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/40e5f673-5389-7706-57ef-fac78e82b635.png)


### ステートマシン
別途定義している**パラメータ値に対して条件を設定し、条件を満たしたら別のステートに遷移する**という形で状態遷移を定義する。

例. 「BaseLayer」のステートマシン
![スクリーンショット 2021-01-31 13.45.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/32e0dcc3-5f1b-8ae2-25e4-34207cf24c2a.png)

**□がステート**であり、**矢印が遷移**を表す。
**「Entry」が指すステートはデフォルトのステート(最初の状態)**である。


例. 遷移条件(Idle → Locomotion)

![スクリーンショット 2021-01-31 13.56.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/62f68727-e68b-e9e1-22cd-5381bf9d59e2.png)

ステートマシン内の遷移矢印をクリックすると表示される。
この例では、以下の**条件をすべて満たしたときに遷移**する。

- Speed > 0.1
- Aim == false
- Grounded == true

例. ステート(jump_start)
![スクリーンショット 2021-01-31 13.57.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/d78f2ade-abf1-57e0-1e92-66f480787a4e.png)

jump_startというアニメーションが設定されている。
Motion内のjump_startをクリックすると、Assetsフォルダ内のアニメーションクリップファイルを強調してくれる。**アニメーションクリップファイルをダブルクリックするとそのアニメーションを開いて動作を確認することができる。**

### アニメーションクリップ
**アニメーション自体のファイル(*.anim)。**
アニメーターが作成したり、モーションキャプチャーで作成したりする。

「AnimatorController」のステートマシンにおいて**各ステート単位でアニメーションクリップを設定する。各ステート単位で設定するアニメーションクリップは1つとは限らず、任意のパラメータによって「ブレンド」することができる。**

### アニメーションのブレンド
各ステートごとに1つだけアニメーションクリップを設定することもできるが、
**「ブレンドツリー」という機能で複数のアニメーションクリップをブレンド(混ぜる)してアニメーションを表現することもできる。**

ブレンドツリーでは、
**「特定のパラメータ値がXのときにアニメーションクリップYの特徴が100%現れるようにする」**という形で複数のアニメーションクリップとしきい値を設定する。
この設定にもとづいて、**パラメータ値がしきい値に近いほどそのアニメーションクリップの特徴が現れる**ようになる。

例. アセット「3rdPerson+Fly」のAnimatorController「CharacterController」内のステート「Locomotion」に設定されているブレンドツリー
![スクリーンショット 2021-01-31 13.35.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/45f7f6f9-bc6f-7cdf-a899-d31fd573284d.png)

``*_fwd``がアニメーションクリップY、Speedが特定のパラメータXでThresholdがそのしきい値にあたる。
なお、 **ブレンドツリーは対象のステートをダブルクリックするとインスペクタビューに表示される。**


### Animatorビュー
インスペクタビューでAnimatorコンポーネントのAnimatorControllerを選択すると表示されるビュー。ステートマシンなどはここで表示できる。

## StateMachineBahavior
各ステートにアタッチし、そのステートの開始時・終了時・途中の毎フレームでの処理を実行させることができるスクリプトのコンポーネント。
対象のステートを選択して、「AddBehavior」でアタッチできる。

**StateMachineBehaviorスクリプトのコード**

```
public class XxxStateBehavior : StateMachineBehaviour
{

    // 当該ステート開始直後のフレームで実行
    public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
    }

    // 当該ステートから別のステートに遷移するフレームで実行
    public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        // パラメータ値は以下のような形で取得できる
        // Float型のパラメータ値の場合
        animator.GetFloat("<パラメータ名>")
        // Bool型のパラメータ値の場合
        animator.GetBool("<パラメータ名>")

        // 現在実行しているアニメーションの状態から正規化された再生時間
        // (1回の開始〜終了までの時間を「1」とする小数の相対値。
        // ループに入るごとに1が加算される)を取得する
        stateInfo.normalizedTime
    }

    // 当該ステートの開始・終了以外の各フレームで実行
    public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
    }
}
```


normalizedTimeの使い道としては、例えば移動時に足が地面に着地したタイミングで足音のSEを再生するといったことに使うことができる。

[【Unity】キャラクターの移動に合わせて足音を付ける方法](https://gomafrontier.com/unity/3191)


## 参考

- [Unity ユーザーマニュアル](https://docs.unity3d.com/ja/2018.4/Manual/index.html)
- [【Unity入門】AnimatorControllerの使い方を解説](https://styly.cc/ja/tips/animator_controller/)
- [アニメーターコントローラー（Animator Controller）の使い方](https://unity-guide.moon-bear.com/animator-controller/)
- [【Unity】キャラクターの移動に合わせて足音を付ける方法](https://gomafrontier.com/unity/3191)
- [【Unity5】StateMachineBehaviourでAnimatorを監視する](https://qiita.com/toRisouP/items/b6540b7f514d18b9a426)