【Unity】任意のAnimation Stateと現在再生されているStateを比較する

はじめに

Animatorのパラメーター/ステートは文字列ではなくハッシュ値で管理するとよい

(例)

protected Animator m_Animator;

//~~~

m_Animator.SetTrigger("Attack");

ではなく

protected Animator m_Animator;

readonly int hashAttack = Animator.StringToHash("Attack");

//~~~

m_Animator.SetTrigger(hashAttack);

の方が好ましい

現在のステートを取得する

AnimatorStateInfo、Animator.GetCurrentAnimatorStateInfoを使用する

docs.unity3d.com

protected AnimatorStateInfo m_CurrentStateInfo;   //現在のハッシュ値が入る
protected Animator m_Animator;

void Awake(){
   m_Animator = GetComponent<Animator>();
}

void Update(){
    m_CurrentStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
}

Base Layerのみを使う場合

f:id:sirataki76:20200922203926p:plain

protected AnimatorStateInfo m_CurrentStateInfo;
protected Animator m_Animator;

//State Hash
readonly int hashStateLocomotion = Animator.StringToHash("Locomotion");

void Awake(){
   m_Animator = GetComponent<Animator>();
}

void Update(){
    m_CurrentStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);    //Base Layerのみの取得なので0を入れる

    Debug.Log(IsStateLocomotion());
}

bool IsStateLocomotion(){
    bool isState = m_CurrentStateInfo.shortNameHash == hashStateLocomotion;

    return isState;
}

 

いくつかのLayerを組み合わせて使う場合

例としてBase Layerの他にAttack、Damage用にの2つのレイヤーを追加したもの(計3つのレイヤー)を使用する

f:id:sirataki76:20200922211520p:plain

複数のレイヤーからStateを比較するときはfullPathHashを使って比較する

protected AnimatorStateInfo[] m_CurrentStateInfo = new AnimatorStateInfo[3];
/*
protected AnimatorStateInfo[] m_NextStateInfo = new AnimatorStateInfo[3];
protected bool[] m_IsAnimatorTransitioning = new bool[3];
*/
protected Animator m_Animator;

//Parameter Hash
readonly int hashAttack = Animator.StringToHash("Attack");

//State Hash
readonly int hashStateLocomotion = Animator.StringToHash("Base Layer.Locomotion");    //Layer名.State名
readonly int hashStateAttack_1 = Animator.StringToHash("Attack.AttackSM.Attack_1");    //Layer名.StateMachine名.State名

void Awake(){
   m_Animator = GetComponent<Animator>();
}

void Update(){
    for(int i = 0; i < 3; ++i){
        m_CurrentStateInfo[i] = m_Animator.GetCurrentAnimatorStateInfo(i);
        /*
        m_NextStateInfo[i] = m_Animator.GetNextAnimatorStateInfo(i);
        m_IsAnimatorTransitioning[i] = m_Animator.IsInTransition(i);
        */
    }
}

bool IsStateLocomotion(){
    bool isState = m_CurrentStateInfo[0].fullPathHash == hashStateLocomotion;

    return isState;
}

bool IsStateAttack(){
    bool isState = m_CurrentStateInfo[1].fullPathHash == hashStateAttack_1;    //AnimatorStateInfo[]のIndexをレイヤーと同じ番号にすること

    return isState;
}

今回はAnimator.GetCurrentAnimatorStateInfoのみを用いたが、他にもAnimator.GetNextAnimatorStateInfoやAnimator.IsInTransitionを使って比較できたりもする

Unity - Scripting API: Animator.StringToHash

Unity - Scripting API: Animator.GetCurrentAnimatorStateInfo

Unity - Scripting API: Animator.GetNextAnimatorStateInfo

Unity - Scripting API: Animator.IsInTransition