Object pooling in Unity with explicit state
Snapshot
~85 sec
Object pooling reuses temporary GameObjects through an explicit acquire, use, reset, and return lifecycle. The important skill is not memorizing a queue, but keeping ownership and reset behavior visible.
You will learn
- Trace one generic GameObject through the full pool lifecycle.
- Connect C# lines to changes in the available and in-use collections.
- Explain why reset belongs inside the release transition.
Target outcome
You can describe and inspect a small Unity pool whose state changes are explicit and repeatable.
Visual walkthrough
Visual walkthrough
~7 min
The pool lifecycle in four concepts
Available
Inactive objects that have been reset and can be acquired.
In use
Objects temporarily owned by the caller and tracked by the pool.
Acquire
Moves one object into use, creating a generic instance only when none is ready.
Release
Ends temporary ownership, resets state, deactivates the object, and returns it.
Acquire, use, reset, return
Trace one generic object through a closed pool cycle. Reset belongs inside release, not after the next caller already inherited stale state.
Ready
Inactive object waits in the available queue.
available.Enqueue(item);requestAcquire
Pool hands out temporary ownership and activates the object.
available.Dequeue(); inUse.Add(item);releaseReset
Release clears temporary state before the object can return.
item.transform.SetPositionAndRotation(...);enqueueReturn
Object deactivates and becomes available again.
item.SetActive(false);
reusesReturn → Ready
Trace one generic object through a closed pool cycle. Reset belongs inside release, not after the next caller already inherited stale state. Reading order
- Ready
Inactive object waits in the available queue.
available.Enqueue(item); - Acquire
Pool hands out temporary ownership and activates the object.
available.Dequeue(); inUse.Add(item); - Reset
Release clears temporary state before the object can return.
item.transform.SetPositionAndRotation(...); - Return
Object deactivates and becomes available again.
item.SetActive(false);
Connection explanations
- Ready → Acquire (request)
Acquire moves one object from ready into temporary ownership.
- Acquire → Reset (release)
Release must verify ownership and clear temporary state before reuse.
- Reset → Return (enqueue)
Only a reset object should re-enter the available queue.
- Return → Ready (reuses)
Return closes the cycle: the same object is ready for a later acquire without a fresh Instantiate.
Make ownership changes explicit in C#
This intentionally small MonoBehaviour shows the state boundary. Production code may add capacity and lifecycle policies, but those details are not needed to understand the transition.
Languagecsharp public sealed class ReusablePool : MonoBehaviour { [SerializeField] private GameObject template; private readonly Queue<GameObject> available = new(); private readonly HashSet<GameObject> inUse = new(); public GameObject Acquire() { var item = available.Count > 0 ? available.Dequeue() : Instantiate(template); item.SetActive(true); inUse.Add(item); return item; } public void Release(GameObject item) { if (!inUse.Remove(item)) return; item.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); item.SetActive(false); available.Enqueue(item); } }Code annotations
Lines 4-5
Keep two explicit collections
The queue represents ready objects and the set represents temporary ownership.
Effect: An object cannot be understood as both ready and in use at the same moment.
Lines 7-15
Acquire and track
The pool reuses a ready object or creates a generic fallback, then activates and records it.
Effect: The available count can decrease while the in-use count increases.
Lines 17-24
Reset before return
Release first verifies ownership, then clears transform state, deactivates, and enqueues.
Effect: The next caller receives an inactive object from a known baseline.
Check ownership before reuse
Why does Release remove the object from inUse before adding it to available?
Expected reasoning
The removal proves that the pool currently owns the release transition. Only then can reset and enqueue move the object back to the available state without duplicating ownership.