Unity: Creating an Object Pooling System

Michael Quinn
Unity Coder Corner
Published in
5 min readOct 6, 2022

Object Pooling is incredibly useful for solving a very specific problem. I am wasting too many resources creating objects that have a very short life in the scene.

Examples of this are bullet holes in walls, impact effects, bullets themselves, etc. In my case, I have a spaceship that loves shooting lasers that get destroyed within 5 seconds. This constant creation and destruction is resource heavy, so Object Pooling is the way to go.

How It Works

The biggest difference is that we are only going to instantiate an object if we have to and we will never destroy an object. Instead of destroying an object, we are going to reuse the object. This is how Object Pooling gets its massive benefit.

Steps To Creating an Object Pool

Step 1: Creating the Script

First we need to create a new script, I named mine PooledObjects. Then we need to create a reference to the object we want to pool and create a collection for the object to be stored in.

I decided to use a List instead of an array because I want to dynamically size the collection to stretch for as many lasers as I need rather than setting the amount at the beginning.

Step 2: Setting up the GameObject

So now that we have the script, without going too far, lets setup the GameObject to hold the script in the scene.

Then we can drag and drop the prefab into our script to set the reference for later.

Step 3: Creating the Actual Object Pooling Logic

Now lets jump head first into creating the object pooling logic. We want this to be a dynamic system without needing to worry how many we need at any time. So if there isn’t a free object in the pool we need the script to instantiate us another.

To do this, we are going to create a new function that will loop through the current pool looking for a free object. If we can’t find one, then we will instantiate a new one. We then take that new instantiated object and add it to the pool. Finally, we either give back the object we found in the pool, or the last added object to the pool(the newly instantiated object).

Step 4: Allowing Another Script To Use The Pool

For this we are just going to create a new public function that can be called by another script to return either the newly created object or one found in the pool.

Optional Step 5: Prove That It Works

To be 100% sure that it is working, we can add some extra logic to count how many times we spawned a new object vs how many times we pulled from the pool.

The entire class with these added checks will look like this.

How To Replace “Instantiate” and “Destroy” With This New Pooling Script

Replacing the old instantiation logic may seem a little complicated at first but is actually very simple.

Instead of instantiating a new object with the position, we are now going to call for the object from the PooledObjects class and then assign their location after we have it.

Instead of destroying an object, we will now just disable it. This allows the pool to reuse the object without having to deal with any Garbage Collection from Unity.

The Old Way

This was the old way we were firing lasers. We grabbed the prefab and then instantiated a new object every time we wanted to fire a new laser.

The New Way

We are going to replace the reference to the prefab with a reference to the PooledObjects class.

Replacing Destroy Object With Disable Object

The last thing we need to do to enable all the benefits of Object Pooling is to change how we handle the laser object once we are done with it. Instead of destroying the object, we are going to disable it so we can reuse it later.

The Old Way

A script on my laser object used the Destroy method to simply destroy the object after 5 seconds.

The New Way

We have to change this to disable the object after a delay instead of destroying the object. There are many ways to do this but I decided to use a coroutine. IMPORTANT: It is incredibly important that you do not put any logic for disabling the object in the Start function. This is because Start will not run again when you activate the object. That is why we are adding the start coroutine logic in OnEnable().

Hit Play And Test It Out

The end result will look like nothing has changed. But if you included the optional step 5 then we can look to the console and see the magic at work.

As you can see, whenever the system can’t grab a disabled object to reuse it the script will instantiate a new one. If it can grab the object, then it will just reuse the object instead of creating a new one.

In the hierarchy it will look like this.

This again shows that the dynamic Object Pooling system is only creating as many objects as it needs and reuses them any chance it can.

Takeaway

Although the Object Pooling system can seem a little intimidating at first, it is an amazing resource to use when you want to reduce resource use when using many objects for a temporary amount of time.

--

--

Michael Quinn
Unity Coder Corner

I’m a foodie and a software engineer. Unity and Unreal developer. See more at MikeQ.dev