Unity中yield return new WaitForSeconds()失效问题求助
修复WaitForSeconds未生效的问题
问题根源
你的代码中,协程HandleHitAnimation刚启动,就立刻执行了Destroy(gameObject)销毁了挂载该脚本的Pikes物体。Unity里协程是依附于所在GameObject的,一旦物体被销毁,协程会直接终止,所以yield return new WaitForSeconds(1)之后的逻辑根本没机会运行。
修复方案
有两种常用解决思路:
方案一:延迟销毁Pikes,等协程执行完毕再销毁
把Destroy(gameObject)从OnTriggerEnter2D移到协程的最后,确保协程完整执行:
修改后的完整代码:
using System.Collections; using UnityEngine; public class Pikes : MonoBehaviour { public int damage = 1; public float speed; public GameObject effect; GameObject player; Animator otherAnimator; void Start() { player = GameObject.FindWithTag("Player"); otherAnimator = player.GetComponent<Animator>(); } private void Update() { transform.Translate(Vector3.left * speed); if(Input.GetKeyDown(KeyCode.R)) { otherAnimator.SetBool("isHitten", false); } } private void OnTriggerEnter2D(Collider2D other) { if (other.CompareTag("Player")) { StartCoroutine(HandleHitAnimation()); other.GetComponent<Player>().health -= damage; Instantiate(effect, transform.position, Quaternion.identity); // 移除此处的Destroy调用 } } private IEnumerator HandleHitAnimation() { Debug.Log("Starting hit animation"); otherAnimator.SetBool("isHitten", true); yield return new WaitForSeconds(1); Debug.Log("Ending hit animation"); otherAnimator.SetBool("isHitten", false); // 协程执行完毕后再销毁自身 Destroy(gameObject); } }
方案二:将协程移至Player对象执行
如果需要立刻销毁Pikes,可以把协程逻辑放到Player的脚本中,让协程依附于Player对象(不会随Pikes销毁而终止):
- 在Player脚本中添加协程方法:
public IEnumerator PlayHitAnimation() { Animator animator = GetComponent<Animator>(); animator.SetBool("isHitten", true); yield return new WaitForSeconds(1); animator.SetBool("isHitten", false); }
- 修改Pikes的
OnTriggerEnter2D方法:
private void OnTriggerEnter2D(Collider2D other) { if (other.CompareTag("Player")) { Player player = other.GetComponent<Player>(); player.health -= damage; // 让Player启动自身的协程 player.StartCoroutine(player.PlayHitAnimation()); Instantiate(effect, transform.position, Quaternion.identity); // 可立刻销毁Pikes Destroy(gameObject); } }
额外提示
- 别在启动协程后立刻销毁承载协程的GameObject,这是Unity协程的常见坑点。
- 若用
Destroy(gameObject, delayTime)延迟销毁,要保证延迟时间不小于协程的等待时长,否则仍会中断协程。
内容的提问来源于stack exchange,提问作者Narek Sargsyan
相关产品推荐
相关产品推荐

