DSPool is an object pooling solution for Unity. It provides various classes for object pooling, such as generic ObjectPool for general use case or ComponentPool for Component pooling with a GameObject as the prefab. Additionally, you can create various kinds of pools with ready-to-use attributes.
To install, paste the following URL into Unity's Package Manager:
- Open Package Manager.
- Click the + button.
- Select "Add package from git URL...".
- Enter:
https://github.com/hoangtongvu/DSPool.git?path=/Assets/DSPoolComponentPool Example:
public class Example : MonoBehaviour
{
private ComponentPool<MeshRenderer> meshRendererPool;
[SerializeField] private GameObject prefab;
private void Awake()
{
this.meshRendererPool = new()
{
Prefab = this.prefab,
};
}
void Start()
{
// Pre-warm objects in advance
this.meshRendererPool.Prewarm(10);
// Rent an object from the pool
var instance = this.meshRendererPool.Rent();
// Return the object back to the pool after use
this.meshRendererPool.Return(instance);
}
}Regular class pool Example:
public class Foo { }
public class FooPool : ObjectPool<Foo>
{
protected override Foo InstantiateElement() => new Foo();
protected override void OnRent(Foo element)
{
// Add operations before the element being rented
}
protected override void OnReturn(Foo element)
{
// Add operations before the element returned to the pool
}
}
var pool = new FooPool();
pool.Prewarm(10);
var instance = pool.Rent();
pool.Return(instance);
// Get the number of unused objects in the pool
int count = pool.Count;
// Clear all objects in the pool
pool.Clear();
// Dispose the pool
pool.Dispose();You can create your custom pool by inheriting from ObjectPool<T>.
public class Foo { }
public class FooPool : ObjectPool<Foo>
{
protected override Foo InstantiateElement() => new Foo();
protected override void OnRent(Foo element)
{
// Add operations before the element being rented
}
protected override void OnReturn(Foo element)
{
// Add operations before the element returned to the pool
}
}Additionally, you can use ready-to-use attributes to custom your pool even further:
[DSPoolUsePrefab(typeof(T))]: Generate a Prefab of typeTfor the pool[DSPoolSingleton]: Generate a lazy-initialized singleton for the pool, access viaSomePool.Instance[DSPoolManualSingleton]: Generate a manual-initialized singleton for the pool, suitable for pools that can not be initialized vianew()(require prefab or any additional fields)
Note:
[DSPoolSingleton]and[DSPoolManualSingleton]can't be put together on the same pool as they serve the same singleton purpose
[DSPoolUsePrefab(typeof(GameObject))]
public partial class FooPool : ObjectPool<Foo>
{
protected override Foo InstantiateElement()
=> Object.Instantiate(this.Prefab).GetComponent<Foo>();
}
// Auto-genertated from [DSPoolUsePrefab(typeof(GameObject))]
public partial class FooPool
{
public GameObject Prefab { get; set; }
}// Auto-genertated from [DSPoolSingleton]
public partial class FooPool
{
private static FooPool instance;
public static FooPool Instance => instance ??= new();
public static void DestroyInstance()
{
instance = null;
}
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
public static void ClearOnLoad() => DestroyInstance();
#endif
}// Auto-genertated from [DSPoolManualSingleton]
public partial class FooPool
{
private static bool isInstanceInitialized;
private static FooPool instance;
public static FooPool Instance => instance ?? throw new NullReferenceException("FooPool_Singleton hasn't been initialized");
public static bool IsInstanceInitialized => isInstanceInitialized;
public static void InitializeInstance(FooPool newInstance)
{
if (newInstance == null) throw new NullReferenceException("Can not initialize null instance for FooPool_Singleton");
isInstanceInitialized = true;
instance = newInstance;
}
public static void DestroyInstance()
{
isInstanceInitialized = false;
instance = null;
}
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
public static void ClearOnLoad() => DestroyInstance();
#endif
}PoolMap<TPoolKey, TPool, TPoolElement> is a dictionary with the key is TPoolKey and value is TPool
public enum UIType
{
HealthBar = 0,
ToolBar = 1,
StatusBar = 2,
}
public class UICtrl : MonoBehaviour { }
var poolMap = new PoolMap<UIType, ComponentPool<UICtrl>, UICtrl>();
// Add pools to the poolMap
poolMap.Pools.Add(UIType.HealthBar, new()
{
Prefab = someHealthBarPrefab,
});
// Can rent and return objects to the poolMap just like a normal pool
var instance = poolMap.Rent(UIType.HealthBar);
poolMap.Return(instance);Additionally, you can create your own PoolMap and add [DSPoolSingleton] on it:
[DSPoolSingleton]
public class UICtrlPoolMap : PoolMap<UIType, ComponentPool<UICtrl>, UICtrl>
{
}