Simple Object Pool For Unity

Note: This post is still under development.

Games are heavily performance dependent and the most expensive operations tend to be memory allocation and deallocation. If you allocate all of your memory up front, hold on to it during gameplay, and then deallocate it at the end, then you can greatly increase performance.

I've implemented an ObjectPool class in Unity which holds a stack of inactive GameObject's and exposes Get and Store methods that the user program to use. The Objects within the ObjectPool must implement the ObjectPoolObject interface to expose activate and deactivate methods, which are called by the ObjectPool's Get and Store methods. Expected activation and deactivation implementations are to activate and deactivate the gameObject of the poolable object and to reinitialize member variables.

The ObjectPool is created using the Type of the ObjectPoolObject you wish to pool, the number of initial objects to instantiate, and a delegate method to do the instantiating.

This implementation is highly flexible, and highly performant. The delegate creation method allows the user to create GameObjects however they wish, and the generic type allows the ObjectPool's Store method to return the exact component you need, so you can avoid calling GetComponent over and over.

ObjectPool also provides a second ObjectPool constructor which just takes a prefab (of type GameObject), and it will create a new creation delegate automatically to Instantiate the prefab, and return the GetComponent call on the generic type.

By allowing the user to specify the Activate and Deactivate methods, this ObjectPool system becomes very flexible. You may, for instance activate and deactivate several components of the ObjectPoolObject and not use gameObject.SetActive, this may result in a performance increase for your system over using gameObject.SetActive.

In my game, I have a third class, a singleton ObjectPoolManager which holds all the prefabs that are to be pooled, and creates and exposes all the ObjectPools that my game will use.

I've grown quite fond of this pattern.

One interesting application of ObjectPools is shown in A Simple Timer For Unity.

ObjectPool

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class ObjectPool where T : ObjectPoolObject
{
    private Stack m_objectStack;
    public int m_initialSize;
    public delegate T CreateObjectDelegate();
    public CreateObjectDelegate m_creationMethod;
    public GameObject m_parentObject; // if this is set, objects will be created as children of this transform

    public ObjectPool(int initialSize, GameObject prefab) : this (initialSize, null, prefab)
    {

    }

    public ObjectPool(int initialSize, GameObject parentTransform, GameObject prefab) : this(initialSize, parentTransform, 
        delegate {
            GameObject newGameObject = GameObject.Instantiate(prefab);
            return newGameObject.GetComponent();
        })
    {

    }

    public ObjectPool(int initialSize, CreateObjectDelegate creationMethod) : this(initialSize, null, creationMethod)
    { }

    public ObjectPool(int initialSize, GameObject parentObject, CreateObjectDelegate creationMethod)
    {
        m_objectStack = new Stack();
        m_creationMethod = creationMethod;
        m_initialSize = initialSize;
        m_parentObject = parentObject;
        for (int i = 0; i < this.m_initialSize; i++)
        {
            T objectPoolObject = creationMethod();
            Store(objectPoolObject);
            if (m_parentObject != null) {
                objectPoolObject.transform.SetParent(m_parentObject.transform, false);
            }
        }
    }
    
    public T Get(bool create=true)
    {
        T toReturn = null;
        if (m_objectStack.Count == 0)
        {
            if (create) {
                toReturn = m_creationMethod();
            }
            else return null;
        }
        else toReturn = m_objectStack.Pop();

        if (toReturn != null)
            toReturn.ObjectPool_Activate();
        return toReturn;
    }
    
    public void Store(T t)
    {
        t.ObjectPool_Deactivate();
        m_objectStack.Push(t);
    }
}

ObjectPoolObject

using UnityEngine;

public abstract class ObjectPoolObject : MonoBehaviour {
    public abstract void ObjectPool_Activate();
    public abstract void ObjectPool_Deactivate();
}
In