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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 12:05:00