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

Unity 2D中IEnumerator协程无法执行WaitForSeconds问题

问题分析与修复方案

核心问题点

  • Random.Range(1,4)是左闭右开区间,只会生成1、2、3,永远触发不了case4(右方向),得改成Random.Range(1,5)
  • 第一行yield return new WaitForSecondsRealtime(1)末尾缺分号,语法错误会导致代码跑不起来
  • transform.Translate只执行一帧,移动距离微乎其微,根本看不到持续移动的效果
  • 混用transform.Translate和Rigidbody2D,不符合Unity物理逻辑,容易出现冲突
  • 协程执行完一次就结束了,没有循环触发,没法重复随机移动逻辑

修复后的完整代码

private IEnumerator RomeCO() {
    // 循环执行随机移动逻辑,直到切换到Chasing状态
    while (Enemy != Chasing) {
        int MovePick = Random.Range(1, 5); // 修正范围,包含1-4
        
        yield return new WaitForSecondsRealtime(1); // 补上分号
        
        // 先设置旋转角度
        switch (MovePick) {
            case 1:
                Rb.SetRotation(0); // 上
                break;
            case 2:
                Rb.SetRotation(180); // 下
                break;
            case 3:
                Rb.SetRotation(90); // 左
                break;
            case 4:
                Rb.SetRotation(-90); // 右
                break;
        }

        yield return new WaitForSecondsRealtime(1); // 等待旋转完成(可选,看需求调整时间)

        // 根据旋转方向设置持续移动的速度
        Vector2 moveDir = Vector2.zero;
        switch (MovePick) {
            case 1:
                moveDir = Vector2.up;
                break;
            case 2:
                moveDir = Vector2.down;
                break;
            case 3:
                moveDir = Vector2.left;
                break;
            case 4:
                moveDir = Vector2.right;
                break;
        }

        // 持续移动指定时间(比如2秒)
        float moveDuration = 2f;
        float timer = 0f;
        while (timer < moveDuration && Enemy != Chasing) {
            Rb.velocity = moveDir * EnemySpeed;
            timer += Time.deltaTime;
            yield return null; // 等待下一帧
        }

        // 停止移动
        Rb.velocity = Vector2.zero;
        Rb.angularVelocity = 0f;

        // 移动结束后等待一段时间再进行下一次随机选择(可选)
        yield return new WaitForSecondsRealtime(0.5f);
    }
}

额外注意事项

  • 调用协程时要避免重复启动,比如在Update里判断Enemy != Chasing时,加一个标志位控制:
    private bool isRoaming = false;
    
    void Update() {
        if (Enemy != Chasing && !isRoaming) {
            isRoaming = true;
            StartCoroutine(RomeCO());
        } else if (Enemy == Chasing && isRoaming) {
            isRoaming = false;
            StopCoroutine(RomeCO());
            Rb.velocity = Vector2.zero;
        }
    }
    
  • 确保Rb已经在Awake/Start中通过GetComponent<Rigidbody2D>()正确赋值
  • 移动时长、等待间隔都可以根据需求自行调整数值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 18:10:32