unity中animator中Trigger多次觸發動畫的解決方法(基於 stateInfo和ResetTrigger)

SixFlavorsN發表於2024-05-22

巧妙地重置動畫控制器觸發(Reset Triggers)_嗶哩嗶哩_bilibili提出了FSMCleaSignals,會在進和出動畫時使相關的trigger變為非啟用狀態,但是當該動作涉及多layer/多trigger控制時,會在該layer中動作未完成時,其他layer讀取到了還未更改的異常啟用狀態的trigger,從而出錯,這種錯誤主要是由於 animator.SetTrigger在updata中多次呼叫導致的,我們只要透過每一幀updata監聽AnimatorStateInfo中動作的啟用狀態,利用animator.ResetTrigger和animator.SetTrigger對trigger進行實時更正,保證每一幀的trigger在傳遞過資訊啟用動作後在下一幀開始銷燬。

以layer4/動作p4_t1和p4_t2/trigger:p1和p2為例,演示程式碼如下:

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
 
public class touch : MonoBehaviour
{
    private Animator animator;
    AnimatorStateInfo stateInfo;
    // Start is called before the first frame update
    void Start()
    {
        animator = GetComponent<Animator>();
    }
    // Update is called once per frame
    void Update()
    {
        stateInfo = animator.GetCurrentAnimatorStateInfo(4);//監聽的動畫在layer4
        bool t4p1a = stateInfo.IsName("t4_p1");//監聽p1動畫的啟用狀態
        bool t4p2a = stateInfo.IsName("t4_p2");//監聽p2動畫的啟用狀態
        if (t4p1a == true)//當p1動畫在播放時,保證p1和p2的trigeer全處於未啟用狀態
        {
            animator.ResetTrigger("p2");
            animator.ResetTrigger("p1");
        }
        if (t4p2a == true)//當p2動畫在播放時,保證p1和p2的trigeer全處於未啟用狀態
        {
            animator.ResetTrigger("p2");
            animator.ResetTrigger("p1");
        }
        if (t4p1a == false && t4p2a == false)//當沒有動畫在播放時,透過點選,隨機啟用p1和p2中的一個trigger,並在下一幀將其設定為未啟用
        {
            if (Input.touchCount == 1)
            {
                int a = Random.Range(0, 2);
                if (a == 0)
                {
                    animator.SetTrigger("p1");
                    animator.ResetTrigger("p2");
                }
                else if (a == 1)
                {
                    animator.SetTrigger("p2");
                    animator.ResetTrigger("p1");
                }
            }
        }
 
    }
}

初學者,可能我的理解有問題,感謝指正

相關文章