Unity对象池管理器优化:运行时自动扩容指定对象池方案
对象池管理器优化:自动扩容逻辑实现
原代码在对象池内对象耗尽时调用GetPooledObject会触发异常,以下是修改后的完整代码,实现优先从指定对象池获取可用对象,无可用对象时自动创建新对象并加入池的逻辑:
public class ObjectPoolingManager : MonoSingleton<ObjectPoolingManager> { [System.Serializable] public class Pool { public EnemyTypes enemyType; public GameObject prefab; public int size; } [SerializeField] private List<Pool> pools; [SerializeField] private Dictionary<EnemyTypes, Queue<GameObject>> poolDictionary; [SerializeField] private GameObject poolParent; void Start() { PoolingSetup(); } private void PoolingSetup() { poolDictionary = new Dictionary<EnemyTypes, Queue<GameObject>>(); foreach (Pool pool in pools) { Queue<GameObject> objectPool = new Queue<GameObject>(); for (int i = 0; i < pool.size; i++) { var enemy = Instantiate(pool.prefab, poolParent.transform, true); enemy.SetActive(false); objectPool.Enqueue(enemy); } poolDictionary.Add(pool.enemyType, objectPool); } } public GameObject GetPooledObject(EnemyTypes enemyType) { // 安全获取对应类型的对象池,避免键不存在异常 if (!poolDictionary.TryGetValue(enemyType, out var objectPool)) { Debug.LogWarning($"不存在类型为{enemyType}的对象池"); return null; } GameObject objectToSpawn; // 池内有可用对象时直接取出 if (objectPool.Count > 0) { objectToSpawn = objectPool.Dequeue(); } // 池内无可用对象,创建新对象 else { var targetPool = pools.Find(p => p.enemyType == enemyType); if (targetPool == null) { Debug.LogWarning($"找不到类型为{enemyType}的预制体配置"); return null; } objectToSpawn = Instantiate(targetPool.prefab, poolParent.transform, true); // 新对象无需提前入队,回收时会通过ReturnToPool方法加入队列 } objectToSpawn.SetActive(true); return objectToSpawn; } public void ReturnToPool(EnemyTypes enemyType, GameObject objectToReturn) { if (!poolDictionary.ContainsKey(enemyType)) { Debug.LogWarning($"不存在类型为{enemyType}的对象池"); return; } poolDictionary[enemyType].Enqueue(objectToReturn); objectToReturn.SetActive(false); } }
关键修改说明
- 移除原有的
try-catch异常捕获逻辑,改用主动判断队列状态的方式,代码更清晰且避免不必要的异常抛出 - 使用
poolDictionary.TryGetValue安全获取对象池,防止因键不存在导致的KeyNotFoundException - 当队列空时,通过
pools.Find匹配对应类型的预制体配置,动态创建新对象 - 新创建的对象无需提前入队,后续调用
ReturnToPool回收时会自动加入对象池队列
内容的提问来源于stack exchange,提问作者Mengart
相关产品推荐
相关产品推荐

