Search code examples
c#unity-game-enginegame-development

How to reach a specific pool from the list


I have a object pooling manager where I declare the size of the pool from the editor but If the decided pool size is not enough while in playtime I get a error when I try to GetPooledObject. How can I update this code when I try GetPooledObject it tries to get one from the pool and if there is not enough it creates new one and adds it to the specific pool.

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); //buradan poolu bulabiliriz
        }
    }

    public GameObject GetPooledObject(EnemyTypes enemyType)
    {
        GameObject objectToSpawn;
        try
        {
            objectToSpawn = poolDictionary[enemyType].Dequeue();
        }
        catch (Exception e)
        {
            //if there is not enough enemies in the pool then create some more.

            Queue<GameObject> objectPool = new Queue<GameObject>();

            //var enemy = Instantiate(pools.Find().prefab, poolParent.transform, true);

            Debug.Log(pools[0]);
            
            throw;
        }
        
        objectToSpawn.SetActive(true);
    
        return objectToSpawn;
    }
    
    
    public void ReturnToPool(EnemyTypes enemyType, GameObject objectToReturn)
    {
        if (!poolDictionary.ContainsKey(enemyType))
        {
            Debug.LogWarning($"Pool with tag {enemyType} doesn't exist.");
            return;
        }

        poolDictionary[enemyType].Enqueue(objectToReturn);
        objectToReturn.SetActive(false);
    }
}

}


Solution

  • Modify "GetPooledObject" to handle case with empty pool instead of throwing erros:

    public GameObject GetPooledObject(EnemyTypes enemyType)
    {
        if(!poolDictionary.TryGetValue(enemyType, out GameObject objectToSpawn) {
            Pool poolSettings = GetPoolSettings(enemyType);
            objectToSpawn = Instantiate(poolSettings.prefab, poolParent.transform, true);
        }        
        
        objectToSpawn.SetActive(true);
    
        return objectToSpawn;
    }
    
    public Pool GetPoolSettings(EnemyTypes enemyType)
    {
        foreach (Pool pool in pools)
        {
            if(pool.enemyType == enemyType)
            {
                return pool;
            }
            
        }
        return null;
    }