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

Unity中Coroutine执行异常:多次调用问题求助

问题原因与解决办法

原因分析

你在Update()函数里调用StartCoroutine(move()),而Update每帧都会执行一次——这意味着游戏运行时,每帧都会创建一个新的move协程实例。这些协程会各自独立运行,直到物体到达目标位置,所以每个协程结束时都会触发Debug.Log("ct "+count),导致count被多次输出。

另外你的代码还有两个细节会加剧这个问题:

  • 移动速度计算里多乘了0.01f,导致MoveTowards的实际速度极低,物体需要很长时间才能到达目标,这段时间里Update会持续创建大量协程。
  • isHandled变量只能阻止后续协程执行最后的剧情逻辑,但无法阻止协程本身运行到Debug.Log和count++步骤。

解决办法

1. 限制同一时间只运行一个协程

新增一个布尔标记变量,在Update里判断只有当没有协程在运行时,才开启新协程:

private bool isMoving = false;

void Update()
{
    if (!isMoving)
    {
        StartCoroutine(move());
    }
}

public IEnumerator move()
{
    isMoving = true;
    Vector2 tmp = new Vector2(14.47f, transform.position.y);

    // 简化循环逻辑:直接判断是否未到达目标
    while (transform.position.x < tmp.x)
    {
        // 移除多余的0.01f,让移动速度符合预期
        transform.position = Vector3.MoveTowards(transform.position, tmp, moveSpeed * Time.deltaTime);
        yield return null;
    }

    transform.position = tmp;
    Debug.Log("ct "+count);
    count++;

    if (!isHandled)
    {
        isHandled = true;
        GameStoryManager.curGameStoryIndex++;
        animator.SetBool(IS_MOVE_NAME, false);
    }

    isMoving = false;
}

2. 避免在Update里重复调用协程

如果移动只需要触发一次(比如剧情推进、玩家点击触发),直接把StartCoroutine(move())移到触发事件里,而不是放在Update中。比如:

// 示例:在某个触发函数里调用协程
public void TriggerMove()
{
    if (!isMoving)
    {
        StartCoroutine(move());
    }
}

内容的提问来源于stack exchange,提问作者Frank

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:02:08