There are a lot of patterns I was using before they had names, simply because they made the most sense at the time.
You said the Singleton word. Don’t say that word where Sam might here it!
When it comes to object pools, I prefer a generic static class, though that takes a little finagling…
Something like this:
using UnityEngine;
using UnityEngine.Pool;
namespace Pooling
{
public class StaticPool<T> where T : MonoBehaviour, IPoolable
{
private static ObjectPool<T> pool;
public static void InitializePool(T prefab, int defaultCapacity = 10, int maxSize = 10000)
{
if (pool != null) return;
if (!prefab) return;
pool = new ObjectPool<T>(() =>
{
T t = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity);
t.SetDisposeCallback(() => pool.Release(t));
return t;
}, poolable => poolable.gameObject.SetActive(true),
poolable => poolable.gameObject.SetActive(false),
poolable => GameObject.Destroy(poolable),
false,
defaultCapacity,
maxSize);
}
}
public interface IPoolable
{
void SetDisposeCallback(System.Action callback);
}
}
Each different prefab would need it’s own dedicated type… (you’d run into problems with this, for example, if T was a ParticleSystem, but you could create a placeholder type of FlameParticle (which would have to be an IPoolable, then you would have to initialize the system with
StaticPool<FlameParticle>().InitializePool(prefab); //assuming you've linked the prefab to the GO that has this script
The FlameParticle would have to have the SetDisposeCallback() method properly filled in, and the Callback would have to be stored…
Then you’d get a FlameParticle with
FlameParticle fp = StaticPool<FlameParticle>().Get();
When the FlameParticle is no longer needed, it simply invokes the callback to release itself back to the pool.
I just typed that out from memory, so it might need some test runs to be sure I didn’t forget something.