Unity 2D对象池改造:实现屏幕EnemyCount数量恒定需求
基于对象池维持固定敌人数量的实现方案
需求说明
已实现对象池系统,通过复用对象避免重复实例化/销毁开销。需要修改脚本,使屏幕上始终保持Controller.data.enemy1Info.count定义的敌人数量:
- 当前
EnemySpawner.cs按固定间隔持续生成敌人 - 敌人触发触发器时,会调用
ObjectPoolManager.ReturnObjectToPool(gameObject)回收至对象池
修改方案
1. 重构EnemySpawner脚本
核心思路:移除无限循环生成逻辑,改为监控活跃敌人数量,自动补充至目标值,同时通过敌人回收事件同步计数。
修改后的代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class EnemySpawner : MonoBehaviour { [SerializeField] private GameObject enemy1; [SerializeField] private GameObject enemy2; [SerializeField] private GameObject enemy3; [SerializeField] private GameObject enemy4; [SerializeField] private GameObject enemy5; [SerializeField] public GameObject spawnCircle; // 当前活跃的enemy1数量 private int _activeEnemy1Count = 0; // 数量检查间隔(可根据需求调整) [SerializeField] private float countCheckInterval = 1f; void Start() { // 启动enemy1的数量维护协程 StartCoroutine(MaintainEnemy1Count()); // 如需维护其他敌人,可复制上述逻辑,替换对应参数 // StartCoroutine(MaintainEnemyCount(enemy2, () => Controller.data.enemy2Info.count, enemy2Interval)); } /// <summary> /// 持续维护enemy1的数量至目标值 /// </summary> private IEnumerator MaintainEnemy1Count() { while (true) { yield return new WaitForSeconds(countCheckInterval); int targetCount = Controller.data.enemy1Info.count; int needSpawn = targetCount - _activeEnemy1Count; // 批量补充不足的敌人 for (int i = 0; i < needSpawn; i++) { SpawnEnemy(enemy1); } } } /// <summary> /// 生成单个敌人并绑定回收回调 /// </summary> private void SpawnEnemy(GameObject enemyPrefab) { GameObject newEnemy = ObjectPoolManager.SpawnObject( enemyPrefab, getRandomSpawnPoint(), Quaternion.identity, ObjectPoolManager.PoolType.Gameobject ); // 添加回收监听,敌人被回收时更新计数 EnemyDespawnListener listener = newEnemy.GetComponent<EnemyDespawnListener>(); if (listener == null) { listener = newEnemy.AddComponent<EnemyDespawnListener>(); } listener.OnDespawn += () => _activeEnemy1Count--; _activeEnemy1Count++; } /// <summary> /// 外部调用:增加enemy1的目标数量 /// </summary> public void IncreaseEnemySpawnCount() { Controller.data.enemy1Info.count++; } // 获取随机生成点 private Vector3 getRandomSpawnPoint() { int childIndex = Random.Range(0, spawnCircle.transform.childCount); return spawnCircle.transform.GetChild(childIndex).position; } }
2. 添加EnemyDespawnListener辅助脚本
用于监听敌人被回收时的禁用事件,同步更新Spawner的计数:
using UnityEngine; using UnityEngine.Events; public class EnemyDespawnListener : MonoBehaviour { public UnityEvent OnDespawn; private void OnDisable() { // 敌人被回收时触发回调 OnDespawn?.Invoke(); } }
3. ObjectPoolManager无需修改
当前的对象池逻辑已经支持对象的复用与回收,无需额外调整。
关键逻辑说明
- 数量监控:通过协程定期检查活跃敌人数量与目标数量的差值,自动补充不足的敌人
- 计数同步:利用敌人被回收时的
OnDisable事件(ReturnObjectToPool中会调用SetActive(false)),实时减少活跃计数 - 性能优化:避免了无限循环生成的冗余逻辑,仅在数量不足时生成对象,充分利用对象池的复用能力
注意事项
- 确保所有敌人最终都会调用
ObjectPoolManager.ReturnObjectToPool(gameObject),否则计数会出现偏差 - 可调整
countCheckInterval参数:值越小,数量响应越快,性能消耗略高;值越大,性能越好,数量同步延迟越长 - 如需支持多种敌人类型,可将
MaintainEnemy1Count重构为通用方法,传入敌人预制体、目标数量委托等参数
内容的提问来源于stack exchange,提问作者shane
相关产品推荐
相关产品推荐

