Unity Animator 的 SetTrigger 方法有一個小坑,就是快速調用SetTrigger,生效的可能不是最后調用的那個,要是不了解,出問題了會摸不着頭腦。
我遇到問題的場景:來回切換run和idle動作時,會出現本應該播放run的動作時,卻播了idle的動作,從log上看又已經設置過run的trigger。剛開始很着急,完全不知道怎么回事,看上去是偶然的,很難復現。后面經過反復測試,發現快速切換run和idle會使出現問題的概率大大提高,會不會是上一個SetTrigger(idle)覆蓋掉了SetTrigger(run)。於是就做了個小實驗:
1、直接在代碼里同時調用多個SetTrigger;
2、調用多次,但SetTrigger前先ResetTrigger;
測試代碼:
//用臨時變量保存trigger參數,並在播放之前把上一個trigger重置
void SetTrigger(string trigger) { if (!string.IsNullOrEmpty(lastTrigger)) animator.ResetTrigger(lastTrigger); animator.SetTrigger(trigger); lastTrigger = trigger; }
//直接連續調用 public void TestTrigger1() { animator.SetTrigger(AniParam.Run_Trigger); animator.SetTrigger(AniParam.EnterIdle_Trigger); animator.SetTrigger(AniParam.Attack1_Trigger); animator.SetTrigger(AniParam.Attack2_Trigger); animator.SetTrigger(AniParam.Critl_Trigger); }
//每次調用都重置 public void TestTrigger2() { SetTrigger(AniParam.Run_Trigger); SetTrigger(AniParam.EnterIdle_Trigger); SetTrigger(AniParam.Attack1_Trigger); SetTrigger(AniParam.Attack2_Trigger); SetTrigger(AniParam.Critl_Trigger); } void Update() { if (Input.GetKeyDown(KeyCode.A)) TestTrigger1(); if (Input.GetKeyDown(KeyCode.D)) TestTrigger2(); }
測試1,直接SetTrigger,看上去像是動畫融合,而且也不是換調用順序播放:
測試2,先ResetTrigger,再SetTrigger,符合預期: 正常播放Critl:
所以,為了避免SetTrigger異常,出現詭異情況,還是在SetTrigger之前先ResetTrigger吧。