intermediate Utilities

Object Pool

Generic object pooling system to reduce garbage collection. Perfect for bullets, particles, and enemies.

Unity 2022.3+ · 2.1 KB · ObjectPool.cs

How to Use

1

Create a GameObject named 'ObjectPool'

2

Attach this script and define your pools in the inspector

3

Spawn: ObjectPool.Instance.Spawn("bullet", position, rotation)

4

Despawn: ObjectPool.Instance.Despawn("bullet", gameObject)

5

Optionally implement IPoolable on your pooled objects for callbacks

Source Code

ObjectPool.cs
C#
using UnityEngine;
using System.Collections.Generic;

public class ObjectPool : MonoBehaviour
{
    [System.Serializable]
    public class Pool
    {
        public string tag;
        public GameObject prefab;
        public int initialSize = 10;
    }

    public static ObjectPool Instance { get; private set; }

    [SerializeField] private List<Pool> pools;

    private Dictionary<string, Queue<GameObject>> poolDictionary;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
            return;
        }

        poolDictionary = new Dictionary<string, Queue<GameObject>>();

        foreach (var pool in pools)
        {
            var queue = new Queue<GameObject>();
            for (int i = 0; i < pool.initialSize; i++)
            {
                GameObject obj = Instantiate(pool.prefab, transform);
                obj.SetActive(false);
                queue.Enqueue(obj);
            }
            poolDictionary[pool.tag] = queue;
        }
    }

    public GameObject Spawn(string tag, Vector3 position, Quaternion rotation)
    {
        if (!poolDictionary.ContainsKey(tag))
        {
            Debug.LogWarning($"Pool '{tag}' doesn't exist.");
            return null;
        }

        var queue = poolDictionary[tag];
        GameObject obj;

        if (queue.Count > 0)
        {
            obj = queue.Dequeue();
        }
        else
        {
            // Find the prefab and create a new instance
            Pool pool = pools.Find(p => p.tag == tag);
            obj = Instantiate(pool.prefab, transform);
        }

        obj.transform.SetPositionAndRotation(position, rotation);
        obj.SetActive(true);

        if (obj.TryGetComponent<IPoolable>(out var poolable))
            poolable.OnSpawn();

        return obj;
    }

    public void Despawn(string tag, GameObject obj)
    {
        if (obj.TryGetComponent<IPoolable>(out var poolable))
            poolable.OnDespawn();

        obj.SetActive(false);

        if (poolDictionary.ContainsKey(tag))
            poolDictionary[tag].Enqueue(obj);
    }
}

public interface IPoolable
{
    void OnSpawn();
    void OnDespawn();
}