Skip to content

Instantly share code, notes, and snippets.

@Fenikkel
Last active July 9, 2025 07:59
Show Gist options
  • Select an option

  • Save Fenikkel/2f97d1e3acd8b7f1a0fbc217b5a599cc to your computer and use it in GitHub Desktop.

Select an option

Save Fenikkel/2f97d1e3acd8b7f1a0fbc217b5a599cc to your computer and use it in GitHub Desktop.

Revisions

  1. Fenikkel renamed this gist Mar 21, 2025. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. Fenikkel revised this gist Mar 18, 2025. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions info.md
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,8 @@
    # Unity's ObjectPool simplified

    <!--
    <p align="center">
    <img src="https://user-images.githubusercontent.com/41298931/283091278-41f7b098-9fe3-4d71-871d-f85751e6b0de.gif" alt="Singleton example">
    <img src="https://gist.github.com/user-attachments/assets/d9bbb770-49dd-4a4d-a541-ab01e678c5fe" alt="Object pool example">
    </p>
    -->

    &nbsp;
    ## Notes
  3. Fenikkel revised this gist Mar 18, 2025. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions info.md
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,7 @@ Simple tu use and foolproof. It uses abstraction to make it almost invisible on
    &nbsp;
    ## Usage

    1. Inherid on your spawnable object class:
    1. Inherid `PoolableObject` on your spawnable object class:
    ```csharp
    public class MySpawnable : PoolableObject
    {
    @@ -44,7 +44,7 @@ Simple tu use and foolproof. It uses abstraction to make it almost invisible on
    <img src="https://gist.github.com/user-attachments/assets/ec0904f3-a0bd-4a7b-8788-599784db356c" alt="Prefab example">
    </p>

    3. Create a GameObject, attach ObjectPool and assign the `My Spawnable` prefab to the variable `Object Prefab`:
    3. Create a GameObject, attach `ObjectPool` and assign the your spawnable prefab to the variable `Object Prefab`:
    <p align="center">
    <img src="https://gist.github.com/user-attachments/assets/498d966f-87e9-4a1f-8c8d-e596a602675f" alt="Prefab example">
    </p>
  4. Fenikkel revised this gist Mar 18, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion info.md
    Original file line number Diff line number Diff line change
    @@ -44,7 +44,7 @@ Simple tu use and foolproof. It uses abstraction to make it almost invisible on
    <img src="https://gist.github.com/user-attachments/assets/ec0904f3-a0bd-4a7b-8788-599784db356c" alt="Prefab example">
    </p>

    3. Create a GameObject, attach ObjectPool and asign the `My Spawnable` prefab to the variable `Object Prefab`:
    3. Create a GameObject, attach ObjectPool and assign the `My Spawnable` prefab to the variable `Object Prefab`:
    <p align="center">
    <img src="https://gist.github.com/user-attachments/assets/498d966f-87e9-4a1f-8c8d-e596a602675f" alt="Prefab example">
    </p>
  5. Fenikkel renamed this gist Mar 18, 2025. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. Fenikkel renamed this gist Mar 18, 2025. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  7. Fenikkel renamed this gist Mar 18, 2025. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  8. Fenikkel renamed this gist Dec 17, 2024. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  9. Fenikkel renamed this gist Dec 17, 2024. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  10. Fenikkel renamed this gist Dec 17, 2024. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  11. Fenikkel created this gist Dec 17, 2024.
    16 changes: 16 additions & 0 deletions IPoolableObject.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    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();
    }
    77 changes: 77 additions & 0 deletions ObjectPool.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,77 @@
    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
    }
    78 changes: 78 additions & 0 deletions ObjectPool.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,78 @@
    # Unity's ObjectPool simplified

    <!--
    <p align="center">
    <img src="https://user-images.githubusercontent.com/41298931/283091278-41f7b098-9fe3-4d71-871d-f85751e6b0de.gif" alt="Singleton example">
    </p>
    -->

    &nbsp;
    ## Notes
    Simple tu use and foolproof. It uses abstraction to make it almost invisible on your code and easy to reuse it.


    &nbsp;
    ## Usage

    1. Inherid on your spawnable object class:
    ```csharp
    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();
    }
    }
    ```
    2. Create a prefab of the spawnable object:
    <p align="center">
    <img src="https://gist.github.com/user-attachments/assets/ec0904f3-a0bd-4a7b-8788-599784db356c" alt="Prefab example">
    </p>

    3. Create a GameObject, attach ObjectPool and asign the `My Spawnable` prefab to the variable `Object Prefab`:
    <p align="center">
    <img src="https://gist.github.com/user-attachments/assets/498d966f-87e9-4a1f-8c8d-e596a602675f" alt="Prefab example">
    </p>

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

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

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

    &nbsp;
    ## Compatibility
    - 2021.3 or above
    - Any pipeline (Build-in, URP, HDRP, etc)

    &nbsp;
    ## Support
    ⭐ Star if you like it
    ❤️️ Follow me for more
    32 changes: 32 additions & 0 deletions PoolableObject.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    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);
    }
    }