This module is part of the Unity Essentials ecosystem and follows the same lightweight, editor-first approach. Unity Essentials is a lightweight, modular set of editor utilities and helpers that streamline Unity development. It focuses on clean, dependency-free tools that work well together.
All utilities are under the UnityEssentials namespace.
using UnityEssentials;
Install the Unity Essentials entry package via Unity's Package Manager, then install modules from the Tools menu.
-
Add the entry package (via Git URL)
- Window → Package Manager
- "+" → "Add package from git URL…"
- Paste:
https://github.com/EggyStudio/UnityEssentials.git
-
Install or update Unity Essentials packages
- Tools → Install & Update UnityEssentials
- Install all or select individual modules; run again anytime to update
Quick overview: Thread‑safe generic pool with per‑type singletons. Grab items with
Get(), return withReturn(). Pools prewarm and refill in batches, and you can access them viaObjectPools.GetPool<T>()orObjectPools.GetPool(typeof(T)).
A tiny, fast object pooling utility. For value types and classes with a public parameterless constructor, per‑type pools are created on demand. For special types, construct your own ObjectPool<T> with a custom factory. Under the hood it uses a ConcurrentQueue<T> and batch allocation for low contention.
- Per‑type global pools
ObjectPools.GetPool<T>()returns a singleton pool for TObjectPools.GetPool(Type)for non‑generic access and reflection scenarios
- Thread‑safe implementation
- Internally uses
ConcurrentQueue<T>for lock‑free enqueue/dequeue
- Internally uses
- Batch allocation and prewarm
- Pools preallocate an initial batch; when empty they allocate another batch
- Tunable
initialBatchSizeandbatchSizein theObjectPool<T>constructor
- Zero‑config for common cases
- Value types and classes with a public parameterless constructor work out of the box
- Custom factories for special types
- Pass a
Func<T>toObjectPool<T>when you need non‑default construction
- Pass a
- Unity 6000.0+
- No external dependencies
- Using
ObjectPools.GetPool<T>()requiresTto be a value type or a reference type with a public parameterless constructor; otherwise use a customObjectPool<T>with a factory
using UnityEssentials; // For types with a parameterless ctor (or value types) var pool = ObjectPools.GetPool<Bullet>(); var bullet = pool.Get(); // ... initialize/use bullet ... pool.Return(bullet); // make it available again
var poolObj = ObjectPools.GetPool(typeof(Bullet)); var pool = (ObjectPool<Bullet>) poolObj; var bullet = pool.Get(); pool.Return(bullet);
// Suppose Enemy has no public parameterless ctor or needs args var enemyPool = new ObjectPool<Enemy>(() => new Enemy(spawnPoint, difficulty), initialBatchSize: 32, batchSize: 32); var enemy = enemyPool.Get(); // ... enemyPool.Return(enemy);
// Prewarm 500 items; refill in batches of 100 when empty var fxPool = new ObjectPool<Explosion>(() => new Explosion(), initialBatchSize: 500, batchSize: 100);
static class ObjectPoolsObjectPool<T> GetPool<T>()object GetPool(Type type)// returns an ObjectPool boxed as object
class ObjectPool<T>- Ctor:
ObjectPool(Func<T> factory, int initialBatchSize = 100, int batchSize = 100) T Get()– returns an item (allocates a new batch if empty)void Return(T item)– puts the item back into the pool
- Ctor:
- A dictionary caches a single pool per
Type - For
GetPool<T>(), a factory is created usingActivator.CreateInstance(value types and default‑constructible classes) ObjectPool<T>stores items in aConcurrentQueue<T>- If
Get()finds the queue empty,AllocateBatch(batchSize)creates more items via the factory and enqueues them Return(item)simply enqueues the item
- If
- Reset responsibility: The pool doesn’t reset objects; clear/initialize state when you
Get()or beforeReturn() - Double‑return: There’s no guard against returning the same instance twice - track ownership in your code
- Unbounded growth: Pools can grow as needed; there’s no built‑in cap or shrink
- Construction limits:
ObjectPools.GetPool<T>()will fail for types without a public parameterless ctor - use a custom factory in that case - Threading:
ObjectPool<T>is thread‑safe, but your pooled object’s own state may not be; synchronize your use as needed
Runtime/ObjectPool.cs–ObjectPoolsregistry andObjectPool<T>implementationRuntime/UnityEssentials.ObjectPool.asmdef– Runtime assembly definition
unity, pooling, object pool, performance, memory, concurrent, thread‑safe, batch, runtime
