πPool Manager
Used to reuse game objects for optimization purposes
How to use
add using Game.Core;
Only in editor PoolManager will be created automaticaly by SceneSettuper if it doesn't exist yet for test purposes .
PoolSystem prefab must be only in _Loader scene to work properly in build. In _Loader scene you can find PoolSystem in Hierarchy, select it and you will see Prefabs array in the inspector:

You can see Dont Destroy On Load Pools array, in PoolSystem you will add your prefabs that you want to reuse and keep them between scenes (they will be in DontDestroyOnLoad scene).

Pool Size means that we will instantiate 5 objects of coin prefab at startup and you can reuse them in any scene, but keep in mind that if you change parent of Dont Destroy pool object you should parent it back before scene change, or object will be lost (for parent change case it's better to use scene pools). Auto Fill Pool toggle is used to increase pool size runtime if all objects are still active. If you toggle it off -> active object will be reused. Auto fill pools are effective if you don't want to reuse active object and don't know total amount of prefab objects you need in game. Auto Fill Count is used with auto fill pool checker. Leave 0 value and pool will be increased by default const value in PoolManager, or set value >0. This value is responsible of how much new prefab object will be spawned if no more free pool objects to reuse.
How to access pool objects will be described in API section.

Other settings in PoolManager you should keep default: - Sound Pool is used in AudioManager.
For Particle System use stop action = 'Disable', so particle will back to pool after playback.
You should prepare all prefabs for DontDestroyOnLoad pools in _Loader Scene in PoolSystem.prefab
But also you can create scene and DontDestroyOnLoad pools runtime (see examples).
How PoolSystem reuse objects
You should inherit from PoolObject.cs to use OnObjectReuse() virtual method that will be automaticaly called by PoolManager.cs on object resue. You can you Basically pool manager has queues that it iterates through, it checks for PoolObject.cs in prefab on pool creation and if it exist then manager will call OnObjectReuse() when you can PoolManager.instance.Reuse() which returns object from pool.
You can skip inheritance from PoolObject.cs and reuse GameObject without additional scripts by function overrides like ReuseGameObject(GameObject prefab). But you will need to reset object properties manualy after Reuse() call. To return GameObject without PoolObject.cs simply call GameObject.SetActive(false).
When you want to reuse object from pool. You must reference to the same prefab as in PoolManager in Prefabs array. Also you can call Reuse(component) method with component attached to gameObject prefab. If you set reference from scene object -> PoolManager will not find object from pool.
How to use scene pools
Scene pools are perfect if you need pool only in specific scene and not between scenes.
Create PoolsScene object in scene, where you will set your prefabs. You can use GameObject create menu in scene hierarchy:


Now you can fill pools in inspector and they will be created on Awake before any other game script so you can reuse objects in Awake().
Or you can create scene pools runtime, then you need to follow below steps.
Reference to gameObject prefab that you want to instantiate in pool from script;
Create scene pool on Awake/Start method in your script;
Call Reuse/ReusePoolObject methods from PoolManager to get objects.
Here is snippet for creation and use:
// creating pool (in that case it's scene const pool):
PoolManager.instance.CreateSceneConstPool(_cubePrefab, poolSize: 20, transform);
// to get object:
PoolManager.instance.Reuse(_cubePrefab); // generic method for all pools
// or if _cubePrefab has PoolObject.cs script attached you can use
var poolObjectInstance = PoolManager.instance.ReusePoolObject(_cubePrefab);API
public class PoolManager : MonoBehaviour {
public static PoolManager instance;
/// <summary>
/// Call this method on scene change to deactivate all existing pool objects
/// </summary>
public void DeactivateActivePoolObjects() {
PoolObject.OnDeactivateAllPoolObjects.Invoke();
}
public void CreateDontDestroyPool(PoolSettings poolSettings);
/// <summary>
/// Pool that gives only deactivated objects, if there is no free objects - creates new ones runtime <br>
/// attached to active scene, so on scene change will be destroyed</br>
/// </summary>
public void CreateScenePool(PoolSettings poolSettings);
/// <summary>
/// Clean ups all objects of prefab from pool and holder itself
/// </summary>
/// <param name="prefab">pool prefab</param>
public void DestroyPool(GameObject prefab)
/// <summary>
/// Generic method for all pool types. <br>
/// If you know what pool type is used for this component you can use direct method for it </br>
/// </summary>
/// <returns>GameObject from pool</returns>
public GameObject Reuse(GameObject prefab);
/// <summary>
/// Generic method for all pool types where gameObjects have PoolObject script. <br>
/// If you know what pool type is used for this component you can use direct method for it </br>
/// </summary>
/// <returns>PoolObject or it's inheritance component on object that just been reused</returns>
public T ReusePoolObject<T>(GameObject prefab) where T : PoolObject;
/// <summary>
/// Generic method for all pool types where gameObjects have PoolObject script. <br>
/// If you know what pool type is used for this component you can use direct method for it </br>
/// </summary>
/// <returns>PoolObject or it's inheritance component on object that just been reused</returns>
public T ReusePoolObject<T>(T poolObjectPrefabComponent) where T : PoolObject;
/// <summary>
/// Reuse sound object
/// </summary>
public Sound ReuseSound();
// below methods are direct reuse of pool object if you know scene or dontDestroy pool
// it's a bit faster then Reuse/ReusePoolObject() methods
public PoolObject ReusePoolObjectScenePool(GameObject prefab);
public PoolObject ReusePoolObjectDontDestroyPool(GameObject prefab);
public GameObject ReuseGameObjectScenePool(GameObject prefab);
public GameObject ReuseGameObjectDontDestroyPool(GameObject prefab);
/// <summary>
/// Is pool of targetPrefab exists
/// </summary>
public bool HasPoolOf(GameObject targetPrefab);
}Examples
// declare prefab reference.
[SerializedField] private GameObject prefab;
private void Awake() {
PoolManager.instance.CreateScenePool(prefab, 20, transform);
}public class Bullet : PoolObject {
public void Fly(Vector3 direction) {
// some implementations of bullet fly
}
}
public class Weapon : MonoBehaviour {
// assume that I added bulletPrefab in _Loader scene PoolSystem obj
// so no need to create pool runtime.
[SerializedField] private Bullet bulletPrefab;
[SerializedField] private Transform bulletSpawnPoint;
public void Shoot() {
// I know that bulletPrefab has Bullet.cs script, so I can
// safely cast PoolObject.cs to Bullet.cs script
// but it's only possible if we inherit class from PoolObject
var bullet = PoolManager.instance.Reuse(bulletPrefab);
// set it spawn position
bullet.transform.SetPositionAndRotation(bulletSpawnPoint.position,
bulletSpawnPoint.rotation);
// now,
// tell bullet to fly in target direction
bullet.Fly(bulletSpawnPoint.forward);
}
}More project Examples in Assets/_Main/_Examples/Pool System.
Last updated