Skip to content

Instantly share code, notes, and snippets.

@Fenikkel
Last active March 21, 2025 10:02
Show Gist options
  • Save Fenikkel/2f97d1e3acd8b7f1a0fbc217b5a599cc to your computer and use it in GitHub Desktop.
Save Fenikkel/2f97d1e3acd8b7f1a0fbc217b5a599cc to your computer and use it in GitHub Desktop.
Object Pool

Unity's ObjectPool simplified

Object pool example

 

Notes

Simple tu use and foolproof. It uses abstraction to make it almost invisible on your code and easy to reuse it.

 

Usage

  1. Inherid PoolableObject on your spawnable object class:
    public class MySpawnable : PoolableObject
    {
      public override void OnObjectCreated()
      {
        base.OnObjectCreated();
      }

      public override void OnGetFromPool()
      {
        base.OnGetFromPool();
      }

      public override void OnReleaseToPool()
      {
        base.OnReleaseToPool();
      }

      public override void OnDestroyPooledObject() 
      {
        base.OnDestroyPooledObject();
      }
    }
  1. Create a prefab of the spawnable object:

Prefab example

  1. Create a GameObject, attach ObjectPool and assign the your spawnable prefab to the variable Object Prefab:

Prefab example

  1. Manage the poolable objects through a custom script:
public class MyObjectSpawner : MonoBehaviour
{
    [SerializeField] ObjectPool _ObjectPool;

    public void SpawnObject()
    {
        IPoolableObject poolableObject = _ObjectPool.GetObject();
    }

    public void HideObject(IPoolableObject poolableObject) 
    {
        _ObjectPool.ReleaseObject(poolableObject);
    }
}

 

Compatibility

  • 2021.3 or above
  • Any pipeline (Build-in, URP, HDRP, etc)

 

Support

⭐ Star if you like it
❤️️ Follow me for more

using System;
using UnityEngine;
using UnityEngine.Pool;
public interface IPoolableObject
{
Transform transform { get; } // Force to get only monobehaviours
GameObject gameObject { get; } // Force to get only monobehaviours
public IObjectPool<IPoolableObject> ObjectPool { get; set; }
public void OnObjectCreated();
public void OnGetFromPool();
public void OnReleaseToPool();
public void OnDestroyPooledObject();
}
using UnityEngine;
using UnityEngine.Pool;
public class ObjectPool : MonoBehaviour
{
[SerializeField] GameObject _ObjectPrefab;
[Header("Pool config")]
[SerializeField] int _StartSize = 20;
[SerializeField] int _MaxSize = 100;
[SerializeField] bool _ColectionCheck = true; // Only works in editor: throw an exception if we try to return an existing item, already in the pool
IObjectPool<IPoolableObject> _ObjectPool;
private void Awake()
{
_ObjectPool = new ObjectPool<IPoolableObject>(CreateObject, OnGetFromPool, OnReleaseToPool, OnDestroyPooledObject, _ColectionCheck, _StartSize, _MaxSize);
}
#if UNITY_EDITOR && false
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
IPoolableObject spawnableObject = GetObject();
Debug.Log($"Spawned {spawnableObject.gameObject.name}");
}
}
#endif
public IPoolableObject GetObject()
{
return _ObjectPool.Get();
}
public void ReleaseObject(IPoolableObject pooledObject)
{
_ObjectPool.Release(pooledObject);
}
#region ObjectPool callbacks
private IPoolableObject CreateObject()
{
GameObject goInstance = Instantiate(_ObjectPrefab.gameObject);
IPoolableObject spawnableObject = goInstance.GetComponent<IPoolableObject>();
if (spawnableObject == null)
{
Debug.Log($"{_ObjectPrefab.name} must have the {typeof(IPoolableObject)} interface inplemented.");
return null;
}
goInstance.name = $"{spawnableObject.GetType()}"; // $"{spawnableObject.GetType()} {_ObjectPool.CountAll}" -> Unity 6 or above
spawnableObject.ObjectPool = _ObjectPool;
spawnableObject.OnObjectCreated();
return spawnableObject;
}
private void OnGetFromPool(IPoolableObject spawnableObject)
{
spawnableObject.OnGetFromPool();
}
private void OnReleaseToPool(IPoolableObject spawnableObject)
{
spawnableObject.OnReleaseToPool();
}
private void OnDestroyPooledObject(IPoolableObject spawnableObject)
{
Debug.LogWarning("OnDestroyPooledObject");
spawnableObject.OnDestroyPooledObject();
}
#endregion
}
using UnityEngine;
using UnityEngine.Pool;
public class PoolableObject : MonoBehaviour, IPoolableObject
{
IObjectPool<IPoolableObject> _ObjectPool; // Reference to his object pool
public IObjectPool<IPoolableObject> ObjectPool
{
get { return _ObjectPool; }
set { _ObjectPool = value; }
}
public virtual void OnObjectCreated()
{
}
public virtual void OnGetFromPool()
{
gameObject.SetActive(true);
}
public virtual void OnReleaseToPool()
{
gameObject.SetActive(false);
}
public virtual void OnDestroyPooledObject()
{
Destroy(gameObject);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment