What is wrong with my Object pooling (pre-made only 1 object)

is there any bug with the Unity Object pooling library or something wrong with my code? only instantiate one object, even due I set initialize to 8 and maximum to 8.

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;

public class PoolSystemManager : MonoBehaviour
{
    public static PoolSystemManager _Instance { get; private set; }

    public enum PoolType
    {
        None,
        Fern01,
        FernSword,
        Bush01
    }

    [Serializable]
    public struct Pool
    {
        public PoolType poolKey;  // Enum pool key
        public GameObject prefab;         // Prefab to pool
        public int initialPoolSize;        // Initial pool size
        public int maxPoolSize;            // Max pool size
        public Transform parent;           // Parent object for organizing the pooled objects
    }

    [SerializeField]
    private List<Pool> pools;  // List of pools to be created, editable in the inspector

    private Dictionary<PoolType, ObjectPool<IPoolableObject>> poolDictionary;


    private void Awake()
    {
        if (_Instance == null)
        {
            _Instance = this;
        }
        else
        {
            Destroy(gameObject);
            return;
        }

        InitializePools();
    }

    // Initialize all pools based on the inspector list
    private void InitializePools()
    {
        poolDictionary = new Dictionary<PoolType, ObjectPool<IPoolableObject>>();

        foreach (var pool in pools)
        {
            if (!poolDictionary.ContainsKey(pool.poolKey))
            {
                ObjectPool<IPoolableObject> objectPool = new ObjectPool<IPoolableObject>(
    createFunc: () => CreatePooledObject(pool.prefab, pool.parent),
    actionOnGet: obj => OnObjectGet(obj),
    actionOnRelease: obj => OnObjectRelease(obj),
    actionOnDestroy: obj => Destroy(obj.GetGameObject()),
    collectionCheck: false,
    defaultCapacity: pool.initialPoolSize,
    maxSize: pool.maxPoolSize);

                poolDictionary[pool.poolKey] = objectPool;

                print(objectPool.CountAll);
                print(objectPool.CountActive);

                // Pre-populate the pool
                PrepopulatePool(pool.poolKey, pool.initialPoolSize);

                print(objectPool.CountAll);
                print(objectPool.CountActive);
            }
            else
            {
                Debug.LogWarning($"Pool with key {pool.poolKey} already exists.");
            }
        }

        Debug.Log("Pools initialized successfully.");
    }

    // Instantiate the prefab and get the IPoolableObject reference
    private IPoolableObject CreatePooledObject(GameObject prefab, Transform parent)
    {

        //// Pick a random prefab from the array
        //int randomIndex = UnityEngine.Random.Range(0, prefabs.Length);
        //GameObject selectedPrefab = prefabs[randomIndex];

        GameObject obj = Instantiate(prefab);
        obj.SetActive(false);
        obj.transform.SetParent(parent);

        IPoolableObject poolableObject = obj.GetComponent<IPoolableObject>();

        return poolableObject;
    }

    private void PrepopulatePool(PoolType poolKey, int count)
    {
        if (poolDictionary.TryGetValue(poolKey, out var pool))
        {
            for (int i = 0; i < count; i++)
            {
                var obj = pool.Get(); // Create the object
                pool.Release(obj);    // Immediately release it to the pool
            }

            Debug.Log($"Pool {poolKey} pre-populated with {count} objects.");
        }
        else
        {
            Debug.LogError($"Pool with key {poolKey} not found.");
        }
    }

    // Called when the object is pulled from the pool
    private void OnObjectGet(IPoolableObject poolableObject)
    {
        poolableObject.OnPoolGet();
        poolableObject.GetGameObject().SetActive(true);
    }

    // Called when the object is released to the pool
    private void OnObjectRelease(IPoolableObject poolableObject)
    {
        poolableObject.OnPoolRelease();
        poolableObject.GetGameObject().SetActive(false);
    }

    // Pull an object from the pool
    public IPoolableObject GetFromPool(PoolType key, Vector3 position = default, Quaternion rotation = default)
    {
        if (poolDictionary.ContainsKey(key))
        {
            IPoolableObject obj = poolDictionary[key].Get();
            obj.GetGameObject().transform.position = position;
            obj.GetGameObject().transform.rotation = rotation;
            return obj;
        }

        return null;
    }

    // Release an object back to the pool
    public void ReleaseToPool(PoolType key, IPoolableObject obj)
    {
        if (poolDictionary.ContainsKey(key))
        {
            poolDictionary[key].Release(obj);
        }
    }

    // Return statistics for debugging
    public string GetPoolStats(PoolType key)
    {
        if (poolDictionary.ContainsKey(key))
        {
            var pool = poolDictionary[key];
            return $"Pool {key}: Active: {pool.CountActive}, Inactive: {pool.CountInactive}, Total:
 {pool.CountAll}";
        }

        return $"Pool {key} not found.";
    }
}

funny, I spent a couple of hours and I can’t find out why this is happening.
and in only a couple of minutes, I made it without Unity library and it works great !!!

the only thing that keeps solving the issue is I heard the Unity pooling system is faster…

You hear a lot of stuff on the internet… Science Fiction author Vernor Vinge likened it to “the net of a million lies.”

Meanwhile, before you wreck your project forever, make sure you even need pooling, and that you are ready and willing to pay the extraordinary costs associated with pooling.

The costs and issues associated with object pooling / pools:

In very rare extremely-high-count object circumstances I have seen small benefits from pooling.

In MOST circumstances, object pooling is a source of complexity, bugs and edge cases while not giving any measurable benefit.

1 Like

hmm, I changed the code and used the UPool Asset and some integration.

about you said in very rare case, sorry but I can’t just accept this statement. object pooling is fantastic!!

if you instantiate and destroy objects in the meantime the player is playing the game it would cause garbage collecting, and it could cause some performance issues, and spikes. why shouldn’t we ready up all the calculation before, like bake the process?

I know the object pooling will increase the memory usage, but every game does tons of things to reduce the CPU Process to spend ms in calculating things like AI, and gameplay,…

use more memory to have the space to handle other logics.

Edit: I read the whole comments, and still I say no. no way the processing of resetting would be that huge, resetting can be done in multiple frames, also you have to make sure you are resetting the things that are really important, you don’t want to waste performance.