You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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销毁而终止):

  1. 在Player脚本中添加协程方法:
public IEnumerator PlayHitAnimation()
{
    Animator animator = GetComponent<Animator>();
    animator.SetBool("isHitten", true);
    yield return new WaitForSeconds(1);
    animator.SetBool("isHitten", false);
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 14:12:45