3.5 KiB
Pooling Manager Execution Flow
Purpose
The pooling system recycles Addressables-backed GameObject instances instead of repeatedly calling Instantiate and Destroy. Each Addressables key owns one runtime pool that tracks active objects, idle objects, and a memory-release timer.
PoolManager loads prefab assets through AddressableManager, so it uses the same Addressables initialization path and loaded-prefab cache as the rest of the project. Runtime instances are ordinary instantiated GameObjects owned by the pool.
Runtime Files
IPoolable.cs: prefab-side lifecycle interface.ObjectPool.cs: owns instances and the loaded prefab reference for one Addressables key.PoolManager.cs: singleton service used by gameplay, server packet handlers, UI code, and effects systems.
Spawn Flow
- Call
PoolManager.Instance.SpawnAsync(...)orPoolManager.Instance.Spawn(...). PoolManagerfinds or creates anObjectPoolfor the Addressables key.- The pool updates its
memoryReleaseTTLfrom the spawn parameter. - If a memory release countdown is running, the pool cancels it.
- The pool reuses an idle object when available.
- If no idle object exists, the pool waits for
AddressableManagerinitialization, loads the prefab withAddressableManager.LoadPrefabAsync(), then instantiates it. - The instance is parented, positioned, rotated, activated, and all
IPoolable.OnSpawn()hooks are called. - If
autoDespawnTime > 0,PoolManagerstarts a version-checked auto-despawn coroutine. - The spawned
GameObjectis returned to the caller.
Despawn Flow
- Call
PoolManager.Instance.Despawn(gameObject)orPoolManager.Instance.Despawn(addressableKey, gameObject). - The target pool validates that the object is currently active.
- All
IPoolable.OnDespawn()hooks are called. - The object is deactivated, parented under the pool root, and pushed into the idle stack.
- When the active count reaches zero, the pool starts the memory release countdown.
Memory Release Flow
- The countdown waits for the latest
memoryReleaseTTLvalue supplied by spawn calls for that key. - A new spawn for the same key cancels the countdown and keeps the prefab plus idle instances available.
- If the countdown completes while active count is still zero, the pool:
- unregisters itself from
PoolManager; - destroys all pooled instances;
- calls
AddressableManager.ForceReleaseAsset(addressableKey)to release the cached prefab asset; - destroys the pool root object.
- unregisters itself from
Auto Despawn Safety
Auto despawn stores the instance spawn version when the coroutine starts. If the object is manually despawned and reused before the timer completes, the version changes and the old coroutine will not despawn the new lifecycle.
Shutdown Flow
PoolManager subscribes to AddressableManager.OnDispose. When the Addressables manager is disposed, all pools release their instances and prefab assets before AddressableManager.ReleaseAllAssets() runs. PoolManager.OnDestroy() also releases all pools as a fallback.
Example
GameObject fx = await PoolManager.Instance.SpawnAsync(
"effects/fireball.prefab",
hitPosition,
Quaternion.identity,
memoryReleaseTTL: 15f,
autoDespawnTime: 2f);
For coroutine-based callers:
PoolManager.Instance.Spawn(
"effects/fireball.prefab",
hitPosition,
Quaternion.identity,
memoryReleaseTTL: 15f,
autoDespawnTime: 2f,
onComplete: spawned => { /* use spawned */ });