Skip to main content

Object Pooling

If you've been working in Game Development for a while you might be familiar with the concept of object pooling. Object pooling lets you reuse objects so you don't have to allocate new memory everytime you want to spawn an Object.

In the ExtensionTools there's a simple solution for pooling GameObjects. This is ideal for situations where you have to spawn a lot of GameObjects from the same Prefab, such as shooting a gun and spawning bullets.

Creating the Object Pool

Creating the Object Pool is very easy to do. Let us take the example of shooting a gun and spawning bullets.

using ExtensionTools.ObjectPooling;
public class Gun : MonoBehaviour
{
[SerializeField]
GameObject m_BulletPrefab;

[SerializeField]
int m_MaximumBullets= 10;

UnityObjectPool m_ObjectPool;
void Start() {
m_ObjectPool = new UnityObjectPool(m_BulletPrefab, m_MaximumBullets, false);
}
}

When we take a look at the declaration of the UnityObjectPool we can see what's happening.

public UnityObjectPool(GameObject prefab,int initialpoolSize=10,bool autoExpand=false, LogLevel logLevel=LogLevel.Warning)

First we pass the BulletPrefab this is the Prefab which will be instantiated and reused. Now we set the initial pool size this is the amount of bullets that we can have concurrently.

And finally we set Auto expand to false, Setting this to true would allow the pool to grow above the initial pool size when needed. Since we disabled this the oldest GameObject will be used instead when we reached the Maximum Pool Size.

Now we can spawn the bullet.

Important! Make sure to reset all the necessary values since we are reusing GameObjects and not spawning new ones

void SpawnBullet() {
GameObject go = m_ObjectPool.SpawnObject(transform.position, Quaternion.identity, this.transform);
go.GetComponent<Rigidbody>().velocity = (transform.forward * 10);
}

Releasing Pooled Objects

In most cases we also want to Release our Objects. This will mark them as inactive and will tell our ObjectPool that they are ready to be reused. This is especially important when enabling autoExpand because the Object Pool will keep creating new Objects when no Objects are marked to be reused.

Releasing an Object is done by getting the UnityPooledObject component on the GameObject and calling Release();

Let's say we want our bullets to be released when they hit an obstacle. We can easily implement this using the EventListener

void SpawnBullet() {
GameObject go = m_ObjectPool.SpawnObject(transform.position, Quaternion.identity, this.transform);
go.GetComponent<Rigidbody>().velocity = (transform.forward * 10);

go.GetEventListener().OnCollisionEntered = null; //We clear all bindings first since we reuse Objects
go.GetEventListener().OnCollisionEntered += (Collision col) => { go.GetComponent<UnityPooledObject>().Release(); };
}