Unity波次系统:Prefab达实例上限停刷 销毁后续刷实现方案
问题根因
原逻辑失效有两个核心问题:
- 计数变量逻辑混淆:原代码的
curZombiesSpawned只在生成敌人时累加,敌人被击杀销毁时从未扣减,数值永远只增不减,一旦碰到同屏上限就永远满足不了curZombiesSpawned < maxZombiesSpawned的生成条件。 - 协程生命周期错误:原
SpawnWave协程用固定次数的for循环执行,循环跑完就直接将状态切为WAITING,没有预留「等待玩家击杀敌人后补充生成」的等待逻辑,也没有检测「本波全部敌人被清空」的波次结束条件。
修复方案
核心是拆分两类计数,把单次循环生成改成持续检测的补刷逻辑,直到本波敌人全部清完再结束波次:
- 拆分三个独立计数,避免逻辑混淆:本波需要生成的总敌人数、本波已经生成的敌人数、当前场上存活的敌人数
- 新增敌人死亡回调,敌人被销毁时同步扣减存活计数
- 重写波次协程逻辑:只要本波还没生成够总数量,就持续按生成速率检测,存活数低于同屏上限就补怪;全部怪生成完后,等待场上存活数归0再结束当前波次。
修正后代码
首先补充类内需要的字段:
[Header("生成配置")] [SerializeField] private int maxZombiesSpawned = 24; // 同屏存活敌人上限 [SerializeField] private GameObject enemyPrefab; // 敌人预制体引用 // 波次运行时计数 private int _currentWaveTotal; private int _currentWaveSpawnedCount; private int _currentAliveZombieCount;
新增敌人死亡时的公开调用方法,必须在敌人被击杀/销毁的逻辑里触发这个方法:
/// <summary> /// 敌人销毁时调用,更新存活计数 /// </summary> public void NotifyZombieDead() { if (_currentAliveZombieCount > 0) { _currentAliveZombieCount--; } }
重写波次生成协程:
IEnumerator SpawnWave (Wave _wave) { // 初始化本波状态 _currentWaveTotal = _wave.count; _currentWaveSpawnedCount = 0; _currentAliveZombieCount = 0; state = SpawnState.SPAWNING; // 第一阶段:持续补怪直到本波总数量生成完毕 while (_currentWaveSpawnedCount < _currentWaveTotal) { // 存活数低于上限时触发生成 if (_currentAliveZombieCount < maxZombiesSpawned) { SpawnEnemy(); } // 按配置的生成速率等待 yield return new WaitForSeconds(1f / _wave.rate); } // 第二阶段:等待场上所有敌人被清空 while (_currentAliveZombieCount > 0) { yield return null; } // 波次完成 state = SpawnState.WAITING; yield break; }
修改生成敌人方法,同步更新正确计数:
void SpawnEnemy() { Transform spawnPoint = spawnPoints[Random.Range(0, spawnPoints.Length)]; // 网络生成敌人 GameObject zombieInstance = PhotonNetwork.InstantiateRoomObject( enemyPrefab.name, spawnPoint.position, spawnPoint.rotation ); // 绑定死亡回调:给敌人脚本传入当前生成管理器的引用,敌人死亡时调用NotifyZombieDead()即可 // 示例:zombieInstance.GetComponent<Zombie>().Init(this); _currentWaveSpawnedCount++; _currentAliveZombieCount++; }
注意事项
- 多人联机模式下,所有生成、计数逻辑必须放在MasterClient端执行,避免多客户端重复计数、重复生成的问题
- 所有触发敌人销毁的分支(玩家击杀、掉出地图销毁、网络异常销毁)都要确保触发死亡回调,否则计数错乱会导致卡波
- 如果需要做生成间隔的随机波动,可以在
WaitForSeconds的参数里加小范围随机值,手感会更接近COD僵尸模式
内容的提问来源于stack exchange,提问作者Evolight
相关产品推荐
相关产品推荐

