記事

Unity Animator Controller - Override Controller の使い方

Unity Animator Controller - Override Controller の使い方
Visitors

目次

1. Animator Override Controller 概要

2. Animator Override Controller 使用方法

3. Animator Override Controller をスクリプト制御する方法

4. Animation Event をスクリプト制御する方法

5. Animator Controller パラメータをコードで制御する方法


Animator Override Controller

1. Animator Override Controller の利点

  1. 現在のアバターコントローラ内のアニメーションクリップを上書きして使える。
  2. 武器バリエーションが多い場合、攻撃/移動/待機などを武器別に分けたい時や、1つのダンスステートに多数のダンスを割り当てたい時に便利。
  3. 動的にクリップ差し替えできるため、Animator を都度修正しなくてよい。


  • Animator Override Controller 適用前

    武器ごとに State を増やすと Animator がすぐに破綻する。

Desktop View


  • Animator Override Controller 適用後

    例えば ComboAttack1 は以前なら斧/槍/片手剣/両手剣の全ステートが必要だったが、
    Override Controller なら 1 ステートで複数武器クリップを対応できる。

Desktop View

Desktop View



2. Animator Override Controller 使用方法

  • まずエディタで Animator Override Controller ファイルを作成し、ベース controller を割り当てる。
  • その後、上書きしたい animation clip を割り当てる。

Desktop View


Desktop View


  • 私のケースではキャラ用 Animator Controller を指定し、その中の全 Animation State に対して override を適用した。

Desktop View



3. Animator Override Controller をスクリプトで制御する方法

  • Animator Override Controller 変数を作成して割り当て、現在 Animator の runtimeAnimatorController に設定した後、clip 名を override する。


  • Animator の State 名ではなく、

Desktop View


  • State に割り当てた Animation Clip 名を key に使う。

Desktop View


スクリプト例

  • animatorOverrideController キャッシュ
1
2
3
4
5
6
    void Start()
    {
        animatorOverrideController = new AnimatorOverrideController(animator.runtimeAnimatorController);

        animator.runtimeAnimatorController = animatorOverrideController;
    }


  • Animation Clip 名をキーに override
  • ここで GetAnimationClip は DataTable から Addressable ロードで clip を返す。
  • 返却 clip を override 対象に割り当てる。
1
2
var animClip = await Managers.DataMgr._toyAnimationData[index_].GetAnimationClip();
animatorOverrideController["common@forspecialaction"] = animClip;


  • 現在再生中 state の時間を見て、アニメ未終了時の重複実行を防ぐ方法

    GetCurrentAnimatorStateInfo(int i) の引数は layer index。
    state 名・時間判定どちらにも使える。

Desktop View

1
2
3
4
5
6
7
8
9
if (fsm.Animator.GetCurrentAnimatorStateInfo(0).IsName("Dance"))
{
    // do something
}

if(fsm.Animator.GetCurrentAnimatorStateInfo(0).normalizedTime < 1.0f)
{
    // do something
}


4. Animation Event をスクリプトで制御する方法

  • 方法は 2 つ: エディタで Animation Clip に直接追加する方法、スクリプトで該当フレームに動的追加する方法。

    Animation Event Reference


  • エディタで割り当てる方法
  • 従来は各 Clip を開いてポイントを作り、呼びたい関数を指定していた。 Desktop View

Desktop View


  • スクリプトで動的生成する方法
  • event.time, event.functionName, event.xxxParameter を設定し、
  • animationClip.AddEvent(event) でイベント登録する。

Desktop View


Desktop View


  • functionName に設定する関数例

Desktop View


  • float/int/string パラメータも動的割り当て可能。

Desktop View

Desktop View



5. Animator Controller パラメータをコードで制御する方法

  • Mono スクリプトを GameObject に付けるのと同様に、StateMachineBehaviour 継承スクリプトは状態ごとに接続可能。
  • 例: OnStateEnter, OnStateExit, OnStateIK, OnStateMove, OnStateUpdate

    StateMachineBehaviour Reference

Desktop View

Desktop View


コード例

  • Animation State が多い場合、または Event を逐一設定するのが面倒/不可能な場合、
  • state enter/exit/update の各タイミングでパラメータを更新できる。
  • 以下は ResetAnimationBool を対象 state に付与し、bool 名と値を設定する例。
  • state へ入る時に bool を true/false へ更新する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations;

public class ResetAnimationBool : StateMachineBehaviour
{
    public string isInteractingBool;
    public bool isInteractingStatus;

    public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex, AnimatorControllerPlayable controller)
    {
        base.OnStateEnter(animator, stateInfo, layerIndex, controller);
        animator.SetBool(isInteractingBool, isInteractingStatus);
    }
}

この記事は著者の CC BY 4.0 ライセンスの下で提供されています。