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

Unity Enemy Wave Spawning波次刷怪异常 无限生成无冷却问题

核心问题定位

你的代码存在4处逻辑错误,直接导致生成异常、波次冷却失效:

  • 协程被每帧重复启动:Update()是Unity生命周期中每帧执行的方法,你在Update中无判断直接调用StartCoroutine(SpawnEnemy())和StartCoroutine(NextWave()),项目运行后会每秒启动数十到上百个独立的生成、波次协程,多协程并行执行生成逻辑,必然出现无限刷怪的问题。
  • 波次触发无互斥锁:判断enemiesAlive == 0就启动NextWave的逻辑没有加状态限制,会在条件满足的所有帧重复启动冷却协程;且冷却结束重置enemiesSpawned = 0后,大量并行的生成协程会立刻检测到生成条件满足,直接跳过等待逻辑持续生成。
  • 流程无全局状态管控:没有标记当前是否处于生成中、冷却中的状态,无法阻断重复的逻辑触发,也没有形成线性的波次流程闭环。
  • 额外逻辑瑕疵:原随机生成点写法用float范围+四舍五入取索引,会导致数组首尾两个生成点的选中概率远低于中间点,极端情况还会出现索引越界。
修正方案

调整逻辑为线性闭环的波次流程,移除Update中所有启动协程的代码,新增状态标记避免重复触发,流程为:初始化波次参数→生成当前波次敌人→等待场上敌人全部被清除→等待波次冷却→波次计数+1→循环下一波
修正后完整代码如下:

using System.Collections;
using UnityEngine;

public class EnemyManager : MonoBehaviour
{
    public Transform[] SpawnPoints;
    public GameObject EnemyPrefab;
    public int waveNumber = 1;
    public int enemiesSpawned;
    public int spawnNumber;
    public int spawnCap = 25;
    public static int enemiesAlive;
    private WaitForSeconds spawnTick = new WaitForSeconds(1f);
    // 状态互斥标记,阻断重复逻辑触发
    private bool isSpawning = false;
    private bool isCoolingDown = false;

    void Start()
    {
        // 仅启动一次主波次循环,禁止在Update中反复启动协程
        StartCoroutine(WaveMainLoop());
    }

    IEnumerator WaveMainLoop()
    {
        while (true)
        {
            // 初始化当前波次参数
            spawnNumber = waveNumber * 5 + 10;
            enemiesSpawned = 0;
            isSpawning = true;
            
            // 等待本波次敌人生成逻辑执行完成
            yield return StartCoroutine(SpawnEnemy());
            isSpawning = false;

            // 等待场上所有敌人被消灭
            yield return new WaitUntil(() => enemiesAlive == 0);

            // 执行波次冷却
            isCoolingDown = true;
            yield return new WaitForSeconds(10f);
            isCoolingDown = false;

            // 波次递进,进入下一轮循环
            waveNumber++;
        }
    }

    IEnumerator SpawnEnemy()
    {
        while(enemiesSpawned < spawnNumber && enemiesAlive < spawnCap)
        {
            yield return spawnTick;
            // 修正随机索引逻辑,用int重载保证生成点概率均等、无越界
            int randomIndex = Random.Range(0, SpawnPoints.Length);
            Instantiate(EnemyPrefab, SpawnPoints[randomIndex].position, Quaternion.identity);
            enemiesAlive++;
            enemiesSpawned++;
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:30:48