I spent a while figuring this out but I think it’s pretty good. I can pool any object by type and it will also organize them in scene hierarchy. Any feedback appreciated.
public class ObjectPool : MonoBehaviour
{
Dictionary<Type, Queue<Component>> pool = new Dictionary<Type, Queue<Component>>();
Dictionary<Type, Transform> sceneParents = new Dictionary<Type, Transform>();
public static ObjectPool Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(this);
}
else
{
Instance = this;
}
}
public T SpawnObject<T>(T prefab, Vector3 position, Quaternion rotation) where T : Component
{
CreatePool(prefab); // creates a new pool of type T if it doesn't exist
if (pool[typeof(T)].Count <= 0) // if pool empty
{
T instance = Instantiate<T>(prefab, position, rotation);
instance.name = $"{prefab.name} Clone ({instance.GetInstanceID()})";
instance.transform.parent = sceneParents[typeof(T)];
pool[typeof(T)].Enqueue(instance);
}
T item = pool[typeof(T)].Dequeue() as T;
item.transform.position = position;
item.transform.rotation = rotation;
item.gameObject.SetActive(true);
return item;
}
public void DespawnObject<T>(T item) where T : Component
{
item.gameObject.SetActive(false);
pool[typeof(T)].Enqueue(item);
}
private void CreatePool<T>(T item) where T : Component
{
if (!pool.ContainsKey(typeof(T)))
{
pool.Add(typeof(T), new Queue<Component>());
sceneParents.Add(typeof(T), new GameObject(item.name).transform);
sceneParents[typeof(T)].parent = this.transform;
}
}
}