前言
ResetTrigger是個(gè)what跪腹?再此之前我并不知道昌腰,準(zhǔn)確說(shuō)看到過(guò)但是并沒(méi)有care开伏。
開(kāi)始了解它,是 因 為 出 BUG 了 T馍獭固灵!
- 項(xiàng)目中播放動(dòng)畫(huà)統(tǒng)一使用全局的一個(gè)通用方法。播放動(dòng)畫(huà)接口調(diào)用SetTrigger劫流。
- 搖桿開(kāi)始移動(dòng)時(shí)巫玻,調(diào)用SetTrigger("Run"),結(jié)束時(shí)祠汇,調(diào)用SetTrigger("Idel")仍秤。
- 當(dāng)角色在run時(shí),點(diǎn)擊了一個(gè)npc可很,觸發(fā)尋路接口移動(dòng)到npc诗力,當(dāng)然尋路開(kāi)始時(shí),也會(huì)在調(diào)用一次settrigger("Run").
- 當(dāng)尋路過(guò)程中我抠,再次控制搖桿移動(dòng)時(shí)(打斷尋路)苇本,沒(méi)有問(wèn)題导坟,但是當(dāng)停止搖桿時(shí),應(yīng)該播放idle動(dòng)作圈澈,但是實(shí)際停止后還是播放run惫周。可是看log康栈。我明明最后一次調(diào)用了SetTrigger("Idle")
So著重看了下SetTrigger递递。
SetTrigger
- SetTrigger可以改變動(dòng)畫(huà)狀態(tài)機(jī)的狀態(tài),用于觸發(fā)動(dòng)畫(huà)
- SetTrigger是四個(gè)接口之一啥么,其他還有SetFloat登舞、SetInt、SetBool
- SetTrigger本質(zhì)上是SetBool悬荣,不同點(diǎn)在于菠秒,SetBool有兩個(gè)可選擇的值,false/true氯迂。但是SetTrigger比較特殊践叠,調(diào)用SetTrigger會(huì)自動(dòng)激活狀態(tài),同時(shí)又會(huì)自動(dòng)設(shè)置狀態(tài)為false嚼蚀。
我們拿一個(gè)案例來(lái)講解一下:
- 當(dāng)搖桿滑動(dòng)時(shí)禁灼,調(diào)用SetTrigger播放run動(dòng)畫(huà),可以在當(dāng)前幀通過(guò)GetTrigger("homerun") 看到激活狀態(tài)是true轿曙。 當(dāng)過(guò)了一幀后弄捕,再次GetTrigger("homerun") 是false〉嫉郏可以看到守谓,trigger會(huì)自動(dòng)回到false。
- 搖桿在滑動(dòng)角色在跑動(dòng)時(shí)您单,又調(diào)用尋路接口斋荞,再次觸發(fā)SetTrigger("homerun"). 這個(gè)時(shí)候,homerun的trigger狀態(tài)又被設(shè)置成true睹限。 但是重要的是:因?yàn)橐呀?jīng)在homerun狀態(tài)了譬猫,unity并不會(huì)重新進(jìn)入這個(gè)狀態(tài)讯檐,所以homerun的trigger狀態(tài)并不會(huì)自動(dòng)進(jìn)入false羡疗。
- 所以在我停止的搖桿的時(shí)候,雖然我調(diào)用了SetTrigger("comidle"), unity會(huì)進(jìn)入idle狀態(tài)别洪,但是因?yàn)閔omerun的trigger狀態(tài)一直是true叨恨,所以進(jìn)入idle狀態(tài)后,又會(huì)進(jìn)入homerun狀態(tài)挖垛。由此引起的bug痒钝。
解決辦法
ResetTrigger
- ResetTrigger() 可以重置那些可能已經(jīng)被激活的Trigger秉颗。
所以SetTrigger() 之前,我們需要清除可能已經(jīng)被激活的Trigger送矩。如下方法:
/// <summary>
/// 清除所有的激活中的trigger緩存
/// </summary>
public void ResetAllTriggers(Animator animator)
{
AnimatorControllerParameter[] aps = animator.parameters;
for (int i = 0; i < aps.Length; i++)
{
AnimatorControllerParameter paramItem = aps[i];
if (paramItem.type == AnimatorControllerParameterType.Trigger)
{
string triggerName = paramItem.name;
bool isActive = animator.GetBool(triggerName);
if (isActive)
{
animator.ResetTrigger(triggerName);
}
}
}
}