Skip to content

Instantly share code, notes, and snippets.

@simonwittber
Last active May 17, 2021 12:06
Show Gist options
  • Save simonwittber/464bea4a28a7cb516bd96e9a0f685fb4 to your computer and use it in GitHub Desktop.
Save simonwittber/464bea4a28a7cb516bd96e9a0f685fb4 to your computer and use it in GitHub Desktop.
The last game object pool you will ever need... maybe.
using System.Collections.Generic;
using UnityEngine;
public class ComponentPool<T> where T : Component
{
static ComponentPool<T> Instance = new ComponentPool<T>();
Dictionary<int, Stack<T>> pools = new Dictionary<int, Stack<T>>();
Dictionary<int, int> instances = new Dictionary<int, int>();
static public void Prewarm(T prefab, int count)
{
var pool = Instance.GetPool(prefab.GetInstanceID());
for (var i = 0; i < count; i++)
Instance.CreateInstance(prefab, pool);
}
static public T Take(T prefab)
{
var poolKey = prefab.GetInstanceID();
var pool = Instance.GetPool(poolKey);
T g;
if (pool.Count == 0)
g = Instance.CreateInstance(prefab, pool);
else
g = pool.Pop();
Instance.instances[g.GetInstanceID()] = poolKey;
g.gameObject.SetActive(true);
return g;
}
static public void Return(T instance)
{
if (instance == null)
Debug.Log("Cannot return a null instance.");
else
{
int poolKey;
var instanceKey = instance.GetInstanceID();
if (Instance.instances.TryGetValue(instanceKey, out poolKey))
{
var pool = Instance.pools[poolKey];
instance.gameObject.SetActive(false);
Instance.instances.Remove(instanceKey);
pool.Push(instance);
}
else
{
Debug.LogWarning("Cannot return an instance that was not taken from a pool.", instance.gameObject);
}
}
}
T CreateInstance(T prefab, Stack<T> pool)
{
var g = GameObject.Instantiate(prefab);
g.gameObject.SetActive(false);
return g;
}
Stack<T> GetPool(int key)
{
Stack<T> pool;
if (!pools.TryGetValue(key, out pool))
pool = pools[key] = new Stack<T>();
return pool;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment