If you’re a game developer looking to optimize your game’s performance (and you should always be), object pooling is a technique you must know! This clever optimization strategy helps reduce the strain on your CPU by minimizing the creation and destruction of GameObjects.
What is Object Pooling?
Object pooling involves maintaining a collection of pre-initialized objects that are ready and waiting in a deactivated state. Instead of instantiating a new GameObject every time you need one, your application simply requests an object from this pool and activates it. Once you’re done with the object, you deactivate it and return it to the pool rather than destroying it.
Why Use Object Pooling?
Using object pools can significantly reduce the stuttering and lag often caused by garbage collection (GC) spikes. These spikes typically occur when a large number of objects are created or destroyed, leading to memory allocation and deallocation. By pre-initializing your object pool at a strategic time—such as during a loading screen—you can avoid these performance hiccups, ensuring a smoother gameplay experience for your users.
How to Implement Object Pooling
- Initialize a Pool: Create a set of GameObjects and keep them deactivated in your pool.
- Request from the Pool: When you need a GameObject, retrieve it from the pool and activate it.
- Return to the Pool: Once you’re done, deactivate the GameObject and return it to the pool for future use.
By integrating object pooling into your game, you can maintain high performance and keep your players immersed in the action without the distraction of unexpected stutters. So, the next time you’re optimizing your game, remember the power of object pooling—your CPU will thank you, and so will your players.
Simple Sample Code
In this example, we’re gonna make a basic pool with only one type of object.
Create a script named Object.cs with the following script:
public class ObjectPool : MonoBehaviour
{
//assign an object you'd like to pool
[SerializeField] private PooledObject objectToPool;
//set how many of this object you'd like to store in the pool
[SerializeField] private uint initPoolSize;
//this collection will store the objects
private Stack<PooledObject> objectStack;
//we're gonna setup the pool at start, but you should evaluate the best moment according to your project's specifications
private void Start()
{
CreatePool();
}
//this function creates the pool
private void CreatePool()
{
objectStack = new Stack<PooledObject>();
PooledObject instance = null;
//do a loop to instantiate clones of the object
for (int i = 0; i < initPoolSize; i++)
{
instance = Instantiate(objectToPool);
instance.Pool = this;
//remember these objects should be inactive until taken out of the pool
instance.gameObject.SetActive(false);
objectStack.Push(instance);
}
//gets the first active GameObject from the pool
public PooledObject GetPooledObject()
{
//if there's no object available in the pool, instantiate a new clone of the requested object
PooledObjects
if (objectStack.Count == 0)
{
PooledObject newInstance = Instantiate(objectToPool);
newInstance.Pool = this;
return newInstance;
}
//otherwise, grab the next available object from the list
PooledObject nextInstance = objectStack.Pop();
nextInstance.gameObject.SetActive(true);
return nextInstance;
}
//returns object to pool after it's not necessary on scene anymore
public void ReturnToPool(PooledObject pooledObject)
{
objectStack.Push(pooledObject);
pooledObject.gameObject.SetActive(false);
}
}
}
Now, attach the script to a GameObject named “ObjectPool” in your scene and fill its empty variables in the Inspector.
To help disabling used objects, you should add the following script as a component on the object:
public class PooledObject : MonoBehaviour
{
private ObjectPool pool;
public ObjectPool Pool { get => pool; set => pool = value; }
//this function will disable the object and return it to the pool
public void Release()
{
pool.ReturnToPool(this);
}
}
Now you have your scene prepared with an object pool and the necessary functions to take and return objects from the pool!
In the next tutorial, I’m gonna talk about the Pool API which as introduced 3 years ago and can also make Object Pooling easier depending on your project!