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

Unity中Coroutine引发异常刷怪问题求助

问题:Unity特殊技能触发后异常刷出大量敌人
  • 原逻辑:敌人数为0时自动刷新新一波敌人,运行正常
  • 新增特殊技能后:使用技能会一次性刷出约20波敌人,日志显示enemyCount.Length先上升至某数值后莫名变为0,导致waveNumber持续增长到18左右

问题根源

  1. 协程重复启动:Player的Update方法中,只要满足specialMove == true && 玩家Y坐标>0.8就会启动SpecialMoveDelay协程,导致同一时间运行多个协程,造成smashCam等状态混乱。
  2. Spawner无防重复刷波机制:FixedUpdate中每帧检测敌人数,当敌人因特殊技能被批量销毁时,会连续多帧满足enemyCount.Length ==0,导致waveNumber持续递增,刷出大量敌人。
  3. Enemy边界判断逻辑错误:CheckFallen方法中Z轴的边界判断重复,导致敌人超出负Z边界时不会被销毁,可能引发状态异常。

修复步骤

1. 修复Player的协程重复启动问题

添加isSpecialMoveRunning标志,防止同一时间启动多个协程:

public class PlayerController : MonoBehaviour
{
    // ... 原有变量 ...
    private bool isSpecialMoveRunning = false; // 新增:协程运行状态标记

    void Update()
    {
        // ... 原有移动逻辑 ...

        // 仅在协程未运行时启动
        if (specialMove == true && gameObject.transform.position.y > 0.8 && !isSpecialMoveRunning)
        {
            StartCoroutine(SpecialMoveDelay());
        }
    }

    IEnumerator SpecialMoveDelay()
    {
        isSpecialMoveRunning = true; // 标记协程启动
        playerRb.constraints = RigidbodyConstraints.FreezePositionY;
        smashCam = true;

        yield return new WaitForSeconds(1);

        specialMove = false;
        smashCam = false;
        playerRb.constraints = RigidbodyConstraints.None;
        playerRb.AddForce(drop * dropForce, ForceMode.Impulse);

        // ... 击飞敌人逻辑 ...

        isSpecialMoveRunning = false; // 标记协程结束
    }

    // ... 其他原有方法 ...
}

2. 修复Spawner的重复刷波问题

添加isSpawning标志,确保每次仅刷一波敌人:

public class SpawnManagerScript : MonoBehaviour
{
    // ... 原有变量 ...
    private bool isSpawning = false; // 新增:刷波状态标记

    void FixedUpdate()
    {
        var enemyCount = FindObjectsByType<EnemyClass>(FindObjectsSortMode.None);
        
        Debug.Log("enemies = " + enemyCount.Length);

        // 仅在无敌人、非技能状态、未在刷波时触发
        if (enemyCount.Length == 0 && playerController.smashCam == false && !isSpawning)
        {
            isSpawning = true;
            waveNumber++;
            Debug.Log("Wave Num = " + waveNumber);
            SpawnEnemyWave(waveNumber);

            Instantiate(powerUpPrefab, GenerateSpawnPoint(), powerUpPrefab.transform.rotation);

            if (waveNumber > 3)
            {
                Instantiate(healthPrefab, GenerateSpawnPoint(), powerUpPrefab.transform.rotation);
            }

            isSpawning = false;
        }
    }

    // ... 其他原有方法 ...
}

3. 修复Enemy的边界判断逻辑

修正CheckFallen方法中的Z轴边界判断错误:

public class EnemyClass : MonoBehaviour
{
    // ... 原有方法 ...

    public void CheckFallen()
    {
        if (transform.position.y < -10)
        {
            Destroy(gameObject);
        }
        // 修复Z轴负方向的边界判断
        if (transform.position.x < -30 || transform.position.x > 30 || transform.position.z < -30 || transform.position.z > 30)         
        {
            Destroy(gameObject);
        }
    }

    // ... 其他原有方法 ...
}

额外优化建议

  • 避免在Update/FixedUpdate中频繁调用FindObjectsByType,可以维护一个敌人列表,在敌人生成/销毁时更新列表,提升性能。
  • 将特殊技能的状态变量(如specialMove、smashCam)改为私有,通过公共方法控制,避免外部误修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:27:05