【Unity】AnimatorControllerのState切り替わり時にState名をログに出す

AnimatorControllerはStateの切り替わりは簡単にスクリプトから取れるけど、Stateの名前を取ったりするのが意外と面倒です。
このあたりのソースコードを毎回作ってると時間がかかるので、手軽にできるようなスクリプトを残しておきます。

AnimatorCotrollerを作る

まずBaseLayerをこんな感じで作ります。

f:id:halya_11:20180531001812p:plain

Sub State MachineにState03も定義しておきます。

f:id:halya_11:20180531001842p:plain

ソースコード

まずはStateInfoからStateのEnumを取得する汎用的な拡張メソッドを定義します。
列挙型のStateはノード名に合わせて定義しておきます。

パフォーマンスは最適化してないです。
ランタイムで使うならもうちょい頑張りたい感じ。

using UnityEngine;

// Stateの定義
// enumの定義名とノードの名前を同一にしておく
public enum SampleState{
    State01,
    State02,
    State03,
}

public static class Extensions{

    public static StateType GetCurrentState<StateType>(this Animator animator, int layerIndex = 0) where StateType: struct{
        var stateInfo = animator.GetCurrentAnimatorStateInfo(layerIndex);
        return stateInfo.GetState<StateType>();
    }

    public static StateType GetState<StateType>(this AnimatorStateInfo stateInfo){
        StateType ret = default(StateType);
        foreach (var state in System.Enum.GetValues(typeof(StateType))) {
            if (stateInfo.IsName(state.ToString())) {
                ret = (StateType)state;
                break;
            }
        }
        return ret;
    }
}

次にこれをStateMachineBehaviourから使います。
今回はOnStateEnter()とOnStateExit()のときにログ出力してみます。

using UnityEngine;

public class AnimatorStateLogger : StateMachineBehaviour {

    public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        base.OnStateEnter(animator, stateInfo, layerIndex);
        Debug.Log("On State Enter: " + stateInfo.GetState<SampleState>());
    }

    public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        base.OnStateExit(animator, stateInfo, layerIndex);
        Debug.Log("On State Exit: " + stateInfo.GetState<SampleState>());
    }
}

実行する

StateMachineBehaviourをBaseLayerにアタッチして実行します。
Animator.Play()とかでStateを切り替えれば、State名がログ出力されるのが確認できるかと思います。