Object Pooling in Unity
In this tutorial, you’ll learn how to create your own object pooler in Unity in a fun 2D shooter. By Mark Placzek.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
In this scenario, you’re outnumbered 1000 to 1. There’s no need to give the Neptunians the upper hand with unexpected memory spikes. Sound familiar? Go ahead and pull up a chair and get up to speed on Object Pooling.
In this Unity tutorial, you’ll learn:
- All about object pooling
- How to pool a game object
- How to expand your object pool at runtime if necessary
- How to extend your object pool to accommodate different objects
By the end of this tutorial, you’ll have a generic script you can readily drop into a new game. Additionally, you’ll understand how to retrofit the same script for an existing game.
Prerequisites: You’ll need to be familiar with some basic C# and how to work within Unity’s development environment. If you need some assistance getting up to speed, check out the Unity tutorials on this site.
Prerequisites: You’ll need to be familiar with some basic C# and how to work within Unity’s development environment. If you need some assistance getting up to speed, check out the Unity tutorials on this site.
What is Object Pooling?
Instantiate()
and Destroy()
are useful and necessary methods during gameplay. Each generally requires minimal CPU time.
However, for objects created during gameplay that have a short lifespan and get destroyed in vast numbers per second, the CPU needs to allocate considerably more time.
Additionally, Unity uses Garbage Collection to deallocate memory that’s no longer in use. Repeated calls to Destroy()
frequently trigger this task, and it has a knack for slowing down CPUs and introducing pauses to gameplay.
This behavior is critical in resource-constrained environments such as mobile devices and web builds.
Object pooling is where you pre-instantiate all the objects you’ll need at any specific moment before gameplay — for instance, during a loading screen. Instead of creating new objects and destroying old ones during gameplay, your game reuses objects from a “pool”.
Getting Started
If you don’t already have Unity 5 or newer, download it from Unity’s website.
Download the starter project, unzip and open SuperRetroShooter_Starter
project in Unity — it’s a pre-built vertical scroll shooter.
Note: Credit goes to Master484, Marcus, Luis Zuno and Skorpio for the medley of art assets from OpenGameArt. The royalty-free music was from the excellent Bensound.
Note: Credit goes to Master484, Marcus, Luis Zuno and Skorpio for the medley of art assets from OpenGameArt. The royalty-free music was from the excellent Bensound.
Feel free to have a look at some of the scripts, such as Barrier; they are generic and useful, but their explanations are beyond the scope of this tutorial.
As you work through everything, it will be helpful to see what’s happening in your game’s Hierarchy during gameplay. Therefore, I recommend that you deselect Maximize on Play in the Game Tab’s toolbar.
Click the play button to see what you have. :]
Note how there are many PlayerBullet(Clone)
objects instantiated in the Hierarchy when shooting. Once they hit an enemy or leave the screen, they are destroyed.
Making matters worse is the act of collecting those randomly dropped power-ups; they fill the game’s Hierarchy with bullet clones with just a few shots and destroy them all the very next second.
In its current state, Super Retro Shooter is a “bad memory citizen”, but you’ll be the hero that gets this shooter firing on all cylinders and using resources more scrupulously.
Time to Get Your Feet Wet
Click on the Game Controller GameObject in the Hierarchy. Since this object will persist in the Scene, you’ll add your object pooler script here.
In the Inspector, click the Add Component button, and select New C# Script. Give it the name ObjectPooler.
Double-click the new script to open it in MonoDevelop, and add the following code to the class:
public static ObjectPooler SharedInstance;
void Awake() {
SharedInstance = this;
}
Several scripts will need to access the object pool during gameplay, and public static instance
allows other scripts to access it without getting a Component from a GameObject.
At the top of the script, add the following using
statement:
using System.Collections.Generic;
You’ll be using
a generic list to store your pooled objects. This statement gives you access to generic data structures so that you can use the List
class in your script.
Note: Generic? Nobody wants to be generic! Everybody wants to be special!
In a programming language like C#, generics allow you to write code that can be used by many different types while still enforcing type safety.
Typically, you use generics when working with collections. This approach allows you to have an array that only allows one type of object, preventing you from putting a dog inside a cat array, although that could be pretty funny. :]
Note: Generic? Nobody wants to be generic! Everybody wants to be special!
In a programming language like C#, generics allow you to write code that can be used by many different types while still enforcing type safety.
Typically, you use generics when working with collections. This approach allows you to have an array that only allows one type of object, preventing you from putting a dog inside a cat array, although that could be pretty funny. :]
Speaking of lists, add the object pool list and two new public variables:
public List<GameObject> pooledObjects;
public GameObject objectToPool;
public int amountToPool;
The naming is fairly self-explanatory.
By using the Inspector in Unity, you’ll be able to specify a GameObject to pool and a number to pre-instantiate. You’ll do that in a minute.
Meanwhile, add this code to Start():
pooledObjects = new List<GameObject>();
for (int i = 0; i < amountToPool; i++) {
GameObject obj = (GameObject)Instantiate(objectToPool);
obj.SetActive(false);
pooledObjects.Add(obj);
}
The for
loop will instantiate the objectToPool
GameObject the specified number of times in numberToPool
. Then the GameObjects are set to an inactive state before adding them to the pooledObjects
list.
Go back to Unity and add the Player Bullet Prefab to the objectToPool variable in the Inspector. In the numberToPool field, type 20.
Run the game again. You should now have 20 pre-instantiated bullets in the Scene with nowhere to go.