Unity Enemy GameObject随机生成异常:大量实例导致崩溃求助
问题修复方案
你的代码出现大量生成敌人导致崩溃的核心原因是敌人销毁时OnEnemyDestroyed可能被重复调用,使currentEnemyCount变为负数,加上Update每帧都会触发批量生成逻辑,短时间内会生成远超预期的敌人。以下是修复后的代码及优化说明:
修复后的完整代码
using UnityEngine; public class EnemySpawning : MonoBehaviour { public GameObject enemyPrefab; // 重命名变量,符合C#命名规范 public int minPos = -16; public int maxPos = 16; public int maxEnemies = 2; public float spawnY = 4; private int currentEnemyCount = 0; void Start() { // 初始化生成目标数量的敌人 SpawnInitialEnemies(); } void Update() { // 只在需要时生成单个敌人,避免批量生成的风险 if (currentEnemyCount < maxEnemies) { SpawnSingleEnemy(); } } // 初始化生成所有需要的敌人 void SpawnInitialEnemies() { for (int i = 0; i < maxEnemies; i++) { SpawnSingleEnemy(); } } // 生成单个敌人,每次只生成一个 void SpawnSingleEnemy() { // 额外加一层判断,防止异常情况下的过度生成 if (currentEnemyCount >= maxEnemies) return; Instantiate(enemyPrefab, GetRandomPos(), Quaternion.identity); currentEnemyCount++; } // 生成随机位置 Vector3 GetRandomPos() { int x = Random.Range(minPos, maxPos); int z = Random.Range(minPos, maxPos); return new Vector3(x, spawnY, z); } // 敌人销毁时调用此方法,添加安全判断防止计数为负 public void OnEnemyDestroyed() { if (currentEnemyCount > 0) { currentEnemyCount--; } } }
关键修改点说明
- 变量命名规范:将
Enemy改为enemyPrefab,更清晰表达变量用途,符合C#编码习惯。 - 拆分生成逻辑:将批量生成拆分为初始化批量生成和单帧单敌人生成,避免异常情况下一次性生成大量敌人。
- 添加安全校验:在
OnEnemyDestroyed和SpawnSingleEnemy中添加边界判断,防止currentEnemyCount出现负数或超过最大值的情况。 - 简化Update逻辑:每帧只尝试生成一个敌人,即使出现异常,也不会短时间内生成数百万个对象导致崩溃。
额外注意事项
- 确保敌人的销毁逻辑中只调用一次
OnEnemyDestroyed:比如在敌人脚本的OnDestroy方法里只调用一次FindObjectOfType<EnemySpawning>().OnEnemyDestroyed();,避免重复调用。 - 如果敌人数量较多,建议使用**对象池(Object Pool)**来替代直接
Instantiate,减少内存开销和性能问题,从根源避免大量生成对象导致的崩溃。
内容的提问来源于stack exchange,提问作者Axton Gagnon
相关产品推荐
相关产品推荐

