[英]How can I wait for the animation to finish then let the code resume?
我試圖讓敵人攻擊玩家,並且敵人通過 animation 進行攻擊,但是當其他人處於活動狀態時,我必須防止 animation 啟動的方法不起作用。 問題是我的方法不起作用。 更具體地說,它基本上不像評論那樣做任何事情。 如果您需要任何代碼,我應該能夠提供。
這是代碼:
IEnumerator PlayAnim(Animator anim, string booleanName)
{
anim.SetBool(booleanName, true);
yield return new WaitForSeconds(anim.GetCurrentAnimatorStateInfo(0).length + anim.GetCurrentAnimatorStateInfo(0).normalizedTime); // I checked and got a value for that number so it should be paused
anim.SetBool(booleanName, false);
}
在上面的代碼中,我在它的開頭和結尾放置了一個調試,當我運行代碼時,它們在同一秒運行,所以我知道它不起作用。
以下是它的調用方式:
public void AttackPlayer(GameObject playerPos, Animator anim, NavMeshAgent agent, GameObject self, bool MultiAttack, float inRange, float inView, float AttackRange, bool isBlocking, bool HasSeenPLayer)
{
if (MultiAttack)
{
MultAttack(playerPos, anim, agent, self, inRange, inView);
}
else
{
anim.SetBool("Attack2", false);
anim.SetBool("Attack3", false);
StartCoroutine(PlayAnim(anim, "Attack"));
}
if (!PlayerPos.FindPlayerPos(AttackRange, playerPos.transform, inView, self, HasSeenPLayer))
{
anim.SetBool("Attack", false);
anim.SetBool("Attack2", false);
anim.SetBool("Attack3", false);
state = State.Chase;
}
}
public void MultAttack(GameObject playerPos, Animator anim, NavMeshAgent agent, GameObject self, float inRange, float inView)
{
if (random == 0) random = Random.Range(1, 5);
if (random == 1)
{
StartCoroutine(PlayAnim(anim, "Attack"));
random = 0;
return;
}
if (random == 2)
{
if (HasParameter("Attack2", anim))
{
StartCoroutine(PlayAnim(anim, "Attack2"));
random = 0;
return;
}
StartCoroutine(PlayAnim(anim, "Attack"));
random = 0;
return;
}
if (random == 3)
{
if (alk != null)
{
alk.particle.gameObject.SetActive(true);
alk.particle.Play();
}
StartCoroutine(AlkAnim(anim, "Attack3"));
random = 0;
return;
}
if (random == 4)
{
BlockPlayer(playerPos, anim, agent, inRange, inView, self);
random = 0;
return;
}
StartCoroutine(PlayAnim(anim, "Attack"));
random = 0;
return;
}
IEnumerator AlkAnim(Animator anim, string booleanName)
{
anim.SetBool(booleanName, true);
yield return new WaitForSeconds(anim.GetCurrentAnimatorStateInfo(0).length + anim.GetCurrentAnimatorStateInfo(0).normalizedTime);
anim.SetBool(booleanName, false);
if (alk != null)
{
alk.particle.Stop();
alk.particle.gameObject.SetActive(false);
random = 0;
}
}
public static bool HasParameter(string paramName, Animator animator)
{
foreach (AnimatorControllerParameter param in animator.parameters)
{
if (param.name == paramName)
return true;
}
return false;
}
void Start()
{
StartCoroutine(GetGood());
}
IEnumerator GetGood()
{
TtF.ChoseChasingWhatStateToAttackPlayer(agent, Player_pos.player, self, anim, MultiAttack, inRange, inView, AttackRange, isBlocking, hasSeenPlayer);
yield return new WaitForSeconds(0.5f);
StartCoroutine(GetGood());
}
我認為您的第一種方法在理論上可行。 唯一的“問題”是,即使您已經在動畫組件中設置了標志,動畫制作器也是幀內最后執行的事情之一(請參閱事件的執行順序)。 所以我認為你只需要給它時間來實際切換 state。
例如,您可以嘗試首先使用yield return new WaitForEndOfFrame ();
在開始等待當前 state 的長度之前。
另一種方法可能是Animator Events 。 您可以在 animation 的最后放置一個事件,然后簡單地讓它調用一個專用方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.