# Pool try to get destroyed object

**URL:** https://discussions.unity.com/t/pool-try-to-get-destroyed-object/1683798
**Category:** Scripting
**Tags:** Scripting, Question, 6.0
**Created:** [September 16, 2025, 3:36pm UTC](https://discussions.unity.com/t/pool-try-to-get-destroyed-object/1683798 "2025-09-16T15:36:59Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![agrDinoo](https://avatars.discourse-cdn.com/v4/letter/a/a183cd/32.png) [@agrDinoo](https://discussions.unity.com/u/agrDinoo)
#### Post date: [September 16, 2025, 3:36pm UTC](https://discussions.unity.com/t/pool-try-to-get-destroyed-object/1683798/1 "2025-09-16T15:36:59Z")

</div>

I’m using **UnityEngine.Pool** in my project, but I ran into an issue.

When I set a low `maxCapacity`, if I take out more objects and then return them to the pool, the extra objects (beyond the capacity) are destroyed as expected. However, on subsequent calls to `Get()`, it looks like the pool is still (accidentally) trying to reuse those destroyed objects, which results in `null`.

Apart from simply increasing the `maxCapacity`, is there a recommended way to avoid this behavior?

```auto
using UnityEngine.Pool;

namespace Game.Controller
{
    public abstract class SystemPool<T> : IObjectPool<T> where T : PoolingObject
    {
        #region ----- Component Config -----

        // Collection checks will throw errors if we try to release an item that is already in the pool.
        protected bool _collectionChecks = true;
        protected int _maxPoolSize = 10;

        private IObjectPool<T> _pool;
        public int CountInactive { get; }

        #endregion

        #region ----- Constructor -----

        public SystemPool(){}

        #endregion
        
        #region ----- Property -----

        protected IObjectPool<T> Pool
        {
            get
            {
                if (_pool == null)
                {
                    _pool = new ObjectPool<T>(CreatePooledItem, _OnTakeFromPool, _OnReturnedToPool,
                        _OnDestroyPoolObject, _collectionChecks, 10, _maxPoolSize);
                }

                return _pool;
            }
        }

        #endregion

        #region ----- Private Function -----

        protected abstract T CreatePooledItem();

        // Called when an item is returned to the pool using Release
        private void _OnReturnedToPool(T obj)
        {
            obj.OnRelease();
            obj.gameObject.SetActive(false);
        }

        // Called when an item is taken from the pool using Get
        private void _OnTakeFromPool(T obj)
        {
            obj.OnGet();
            obj.gameObject.SetActive(true);
        }

        // If the pool capacity is reached then any items returned will be destroyed.
        // We can control what the destroy behavior does, here we destroy the GameObject.
        private void _OnDestroyPoolObject(T obj)
        {
            obj.OnRelease();
            // UnityEngine.Object.Destroy(obj.gameObject);
        }

        #endregion

        #region ----- Implement Function -----

        public T Get()
        {
            return Pool.Get();
        }

        public PooledObject<T> Get(out T v)
        {
            return Pool.Get(out v);
        }

        public void Release(T element)
        {
            lock (Pool)
            {
                if (element.IsRelease())
                {
                    return;
                }
                element.Release();
                element.gameObject.SetActive(false);
                Pool.Release(element);
            }
        }

        public void Clear()
        {
            Pool.Clear();
        }

        #endregion
    }
}

```

---

<div class="post-metadata">

### Author: ![Kurt-Dekker](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/kurt-dekker/32/101578_2.png) [@Kurt-Dekker](https://discussions.unity.com/u/Kurt-Dekker)
#### Post date: [September 16, 2025, 3:47pm UTC](https://discussions.unity.com/t/pool-try-to-get-destroyed-object/1683798/2 "2025-09-16T15:47:20Z")

</div>

> [@agrDinoo](#):
>
> it looks like the pool is still (accidentally) trying to reuse those destroyed objects, which results in `null`.

That sounds like a bug in the pooling code. If it’s not your code then review the API because perhaps you misused it.

The answer is always the same… ALWAYS!

How to fix a NullReferenceException error

Three steps to success:

- Identify what is null ← any other action taken before this step is WASTED TIME
- Identify why it is null
- Fix that

NullReference is the single most common error while programming. Fixing it is always the same.

Some notes on how to fix a NullReferenceException error in Unity3D:

> **[How to find a nullref in Unity3D scripting – PLBM Games](http://plbm.com/?p=221)**

IF YOU STILL WANT TO USE POOLING:

**The costs and issues associated with object pooling / pools:**

> [@Object pooling](https://discussions.unity.com/t/object-pooling/892797/10):
>
> As soon as you implement a pooling system, all of a sudden YOU become responsible for writing specific code zeroing out everything on those recycled objects. Sounds easy if they start out as “just a bullet” or something simple. But then you add a Rigidbody… oh now you need to have code that will set .velocity and .angularVelocity to zero before recycling the object. Oh wait, did I change the .drag field and .inertialTensor fields to get my boomerang feeling right? Now I have to reset that. An…

> [@Object pooling in a tower defense game](https://discussions.unity.com/t/object-pooling-in-a-tower-defense-game/833104/2):
>
> Of course… you just Destroy() them. When you play with object pooling, you basically become the “Inventory Keeper” of all those objects, and you now have to write extra code to do your bidding. This code has to be meticulously correct from a bookkeeping standpoint or else you get issues like what you see above. For 99% of games, object pooling is unlikely to make a visible performance difference. Object pooling can also have a high cost as far as restructuring the lifetime of objects within…

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.

---

<div class="post-metadata">

### Author: ![agrDinoo](https://avatars.discourse-cdn.com/v4/letter/a/a183cd/32.png) [@agrDinoo](https://discussions.unity.com/u/agrDinoo)
#### Post date: [September 16, 2025, 3:56pm UTC](https://discussions.unity.com/t/pool-try-to-get-destroyed-object/1683798/3 "2025-09-16T15:56:51Z")

</div>

Thank you for your feedback.

I’ve checked the code. When returning the object to the pool, I call `SetActive(false)`, and this line still works, which means I’m not returning a null object to the pool.

The null exception is thrown at line 57, when calling `.Get()`, so I think the issue might be inside the pool itself.

---

<div class="post-metadata">

### Author: ![meredoth](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/meredoth/32/92819_2.png) [@meredoth](https://discussions.unity.com/u/meredoth)
#### Post date: [September 16, 2025, 5:18pm UTC](https://discussions.unity.com/t/pool-try-to-get-destroyed-object/1683798/4 "2025-09-16T17:18:32Z")

</div>

Can you confirm whether the pool implementation actually adds destroyed objects back into the pool? From your code, I don’t see any call to `_pool.CountInactive` within your own `CountInactive` implementation. After destroying any extra objects, check the value of `CountInactive`. If it doesn’t increase, then those objects are being destroyed outright rather than returned as `null` to the stack.

It’s also difficult to be certain without seeing the complete code, but are you sure that all derived classes of your `SystemPool` implement `CreatePooledItem` so that it returns a new instance of `T`?

Lastly, what’s the purpose of having an empty public constructor in an abstract class? The only real reason to include one is to maintain backward compatibility in a library or framework, in case you later need to add a constructor with parameters. But in the case of an abstract class, this doesn’t make sense.

It’s very easy to fall into the trap of thinking: _“I’m sure my code is correct, so it must be someone else’s fault that it doesn’t work.”_ But in 99.9% of cases, especially with popular, widely used libraries, the mistake is our own.

---

<div class="post-metadata">

### Author: ![agrDinoo](https://avatars.discourse-cdn.com/v4/letter/a/a183cd/32.png) [@agrDinoo](https://discussions.unity.com/u/agrDinoo)
#### Post date: [September 17, 2025, 2:38am UTC](https://discussions.unity.com/t/pool-try-to-get-destroyed-object/1683798/5 "2025-09-17T02:38:05Z")

</div>

I’ve identified the root cause of the issue.  
UnityEngine.Pool relies on the **CountInactive** property internally for its calculations and object handling. In my implementation, I overlooked providing this, which caused the unexpected behavior.

After updating my code to properly implement `CountInactive`, the pool now works as expected.
