Lean Pool


DOCUMENTATION

What is Lean Pool?

Lean Pool is a lightweight pooling asset, allowing you to easily cache and recycle prefab instances.

Pooling improves spawning performance, despawning performance, and reduces gc alloc.

Lean Pool also works with normal C# classes too.



How do I use it?

Find your code that heavily relies on:

Instantiate( ... );

And replace it with:

Lean.Pool.LeanPool.Spawn( ... );

Next, find your code that heavily relies on:

Destroy( ... );

And replace it with:

Lean.Pool.LeanPool.Despawn( ... );

For example:

var enemy = Lean.Pool.LeanPool.Spawn(enemyPrefab);

...

Lean.Pool.LeanPool.Despawn(enemy);

That's it, you've now implemented Lean Pool!



Why do I have to type Lean.Pool. before everything?

To improve organization, all Lean Pool classes are inside the Lean.Pool namespace.

If you don't like typing Lean.Pool. each time, then you can add the following code to the top of your script:

using Lean.Pool;

You can now just call LeanPool.Spawn(...) etc.



How do I alter the settings?

If you use the steps above then Lean Pool will automatically create pools when you first call LeanPool.Spawn, so to adjust the settings ahead of time you need to manually create the pool.

To do this, right click in your Hierarchy window, and select Lean / Pool. You should now see a GameObject in your scene called LeanGameObjectPool, and it should be automatically selected.

Next, drag and drop your prefab into the Prefab slot, and this will associate this pool with this prefab. You can now adjust the pool settings like the Preload, Capacity, etc.



My Rigidbody velocity isn't being reset!?

By default, Lean Pool doesn't modify any components when spawning or despawning.

This works fine for most components, but some components maintain their state even when deactivated, which requires you to manually reset their state.

The Rigidbody and Rigidbody2D components are two examples that don't reset their own state. When these components are despawned/deactivated they will retain their velocity, and when spawned again they will shoot off with their old velocity.

To fix this, the velocity must reset when despawned. This can be done by adding the LeanPooledRigidbody or LeanPooledRigidbody2D component that comes with Lean Pool.



How do I write custom spawning/despawning code?

There are several ways to do this, each with their pros and cons.


OnEnable and OnDisable messages

LeanPool will activate and deactivate your prefab clones when pooled.

When a component is deactivated, Unity sends it the OnDisable message, and when activated it sends the OnEnable message.

This means you can make a new component that implements OnEnable and/or OnDisable, and attach this component to your prefab.

NOTE  If you use this approach then you can set LeanGameObjectPool.Notification = None, which can improve performance.
NOTE  If your game requires your prefab clone to be deactivated during gameplay before it's despawned, then this approach may give undesired behaviour.


OnSpawn and OnDespawn messages

If you use the LeanGameObjectPool.Notification = Send Message setting, then LeanPool will call the OnSpawn and OnDespawn methods on any components attached to your prefab clone.

This means you can make a new component that implements OnSpawn and/or OnDespawn, and attach this component to your prefab.

The main downside to this approach is that it may have performance overhead, it may interfere with any code that already uses OnSpawn or OnDespawn for something else, and you may make a typo, causing the methods to not get called.

If you need to reset the state of a child GameObjct, then you can use the LeanGameObjectPool.Notification = Broadcast Message setting instead.

NOTE  Broadcasting may be inefficient if your prefab is complex.


IPoolable interface

If you use the LeanGameObjectPool.Notification = IPoolable setting, then LeanPool will call the OnSpawn and OnDespawn methods on any components attached to your prefab clone that implement the Lean.Pool.IPoolable interface.

This is the recommended approach, because it makes the intent of your code clearer. However, if you can use OnEnable and OnDisable instead, then that may give you slightly better performance.

If you need to reset the state of a child GameObjct, then you can use the LeanGameObjectPool.Notification = Broadcast IPoolable setting instead.

NOTE  Broadcasting may be inefficient if your prefab is complex.



How do I increase the performance even more?

You may notice that the Lean.Pool.LeanPool.Spawn and Lean.Pool.LeanPool.Despawn methods work like magic.

This is because they're static methods that search a dictionary to find the pool associated with the prefab clone before performing the actual spawn or despawn code.

This is generally very fast, but if you need to super optimize your game then you may want to access the Lean.Pool.LeanGameObjectPool component itself. If you store a reference to it, then you can call the Spawn and Despawn methods directly.

NOTE  You cannot mix and match LeanPool and LeanGameObjectPool calls to Spawn and Despawn. If you do this, a warning will be thrown.


Why do I get warnings in the console?

This is probably because you did something wrong.

For example, you may have replaced all your Instantiate calls with Spawn calls, but maybe you forgot to replace all your Destroy calls with Despawn calls.

There are many scenarios like this where you can forget what code is instantiating or destroying what, and it causes Lean Pool to throw a warning when it detects soemthing wrong.

However, Lean Pool will (hopefully) not break if you make mistakes like this, becuase I included many safety checks at every step.

If you're having issues tracking down the cause of a warning, then you can add the LeanPoolDebugger component to your prefab. This component actively tracks the current prefab clone, and will tell you exactly when you incorrectly spawn or destroy it.







Assets

Here's a list of all my other assets, please check them out!

You can also view this list on my Asset Store page.

Lean Touch

Lean Touch

Rapidly develop your game with consistent input across desktop & mobile using Lean Touch. This lightweight asset comes with many modular components, allowing you to customize them to your exact project needs!


Lean Touch+

Lean Touch+

Lean Touch+ is an extension to the popular Lean Touch asset, adding many more example scenes.


Lean Localization

Lean Localization

Lean Localization is a localization library that's designed to be as simple to use as possible for both designers, and programmers.


Lean Pool

Lean Pool

Quickly optimize the performance of your games using Lean Pool. Within minutes you can use this lightweight asset to preload, recycle, and limit the spawning of your prefabs.


Lean Transition

Lean Transition

Quickly polish your games using Lean Transition. This asset allows you to easily tween or animate almost anything in your game, making it transition smoothly.


Lean GUI

Lean GUI

Lean GUI is a colllection of components that extend Unity's GUI system, allowing you to rapidly enhance the user experience (UX) of your game's UI.


Lean GUI Shapes

Lean GUI Shapes

Lean GUI Shapes allows you to quickly add lines, rounded boxes, polygons, and much more to your GUI!


Lean Texture

Lean Texture

Lean Texture allows you quickly modify textures in your project with a range of filters, pack them together into channels, and much more!


Lean Texture+

Lean Texture+

Lean Texture+ is an extension to Lean Texture, adding many new types of texture modification tools!


CW Spaceships - Build & Destroy

Spaceships - Build & Destroy

Build your dream spaceship, and then have fun destroying it!


Modular Backgrounds

Modular Backgrounds

Unlock a universe of visual possibilities with Modular Backgrounds. Simply drag and drop these graphics into the background of your scenes.


Paint in 3D

Paint in 3D

Paint all your objects using Paint in 3D - both in game, and in editor. All features are optimized with GPU accelerated texture painting, so you can enjoy consistent performance, even if you paint your objects one million times!


Paint in 2D

Paint in 2D

Paint all your sprites with Paint in 2D. With incredible performance on mobile, WebGL, and much more!


Paint in Editor

Paint in Editor

Paint in Editor unlocks the ability to paint objects in your scene - great for making small tweaks, or even creating entirely new texture sets!


FLOW

FLOW

FLOW allows you to add large scale interactive fluids to your scene - all highly optimized using GPU acceleration.


Destructible 2D

Destructible 2D

Unlock the full potential of your 2D games using Destructible 2D, this asset allows you to quickly convert all your boring solid sprites into fully destructible ones!


Space Graphics Toolkit

Space Graphics Toolkit

Quickly make the space scene of your dreams using Space Graphics Toolkit. This huge collection of space effects can be customized and combined in any way you like, allowing you to quickly make realistic or fantasy worlds. Each feature has been heavily optimized to run on almost any device and platform.


Space Graphics Planets

Space Graphics Planets

Enhance your space scenes using this large pack of high detail volumetric planets. These planets are finished using the powerful planet features from Space Graphics Toolkit (not required).


Volumetric Audio

Volumetric Audio

Unity sounds only emanate from a single point source. This is great for explosions and footsteps, but quite often you need something more advanced. Volumetric Audio is an easy to use package that allows you to define boxes, spheres, capsules, paths, or meshes that sounds can emanate from.






Versions

2.1.0

Updated CW/Common code to latest version.



2.0.2

Moved main build to Unity 2021.3.0f1.
Updated shaders to latest version.



2.0.1

Moved main build to Unity 2020.3.0f1.
Fixed LeanPoolDebugger component requiring a Rigidbody.
Fixed LeanGameObjectPool.DespawnAll method not removing LeanPool.Links.



2.0.0

NOTE  This is a massive update. To update you must first back up your project, delete the root Lean folder, then install the new version.

Changed folder structure to be inside Plugins/CW/LeanPool.
Updated inspector code to support third party assets that implement nested inspectors.



1.4.3

Fixed transform gizmos not appearing in Unity 2021.2.



1.4.2

Updated common library code.



1.4.1

Fixed console warning when changing scenes or exiting play mode.



1.4.0

Moved main build to Unity 2019.4.12f1.
Made LeanGameObjectPool auto detach clones when being destroyed (e.g. changing scenes).



1.3.2

Fixed LeanGameObjectPool.Preload setting.



1.3.1

Added LeanGameObjectPool.Strategy setting.



1.3.0

Fixed LeanGameObjectPool.Persist setting throwing errors in edit mode.



1.2.9

Added LeanPool.Detach methods.
Added LeanGameObjectPool.Detach method.
Fixed inspector error after manually deleting spawned prefab.
Improved spawn consistency compared to Instantiate.



1.2.8

Moved main build to Unity 2018.4.13f1.



1.2.7

In-editor preloaded prefabs now retain their prefab link.
Added inspector warning to LeanGameObjectPool when preloaded objects differ from the prefab.



1.2.6

Moved main build to Unity 2018.4.0f1.
Updated documentation.
Added asmdef.



1.2.5

Added warning when multiple pools manage the same prefab.
Fixed prefab spawning when using multiple scenes.



1.2.4

Improved spawn position consistency.
Added LeanPoolDebugger component.



1.2.3

Initial prefab spawns now begin with their final positions in Awake/OnEnable.
Updated common library code.



1.2.2

Fixed spawn transform being incorrect in some scenarios.
Fixed inspector expand buttons in UI Elements.



1.2.1

Fixed bug in LeanHelper.cs that prevents making builds.



1.2.0

Fixed error when using Unity 2018.3+.



1.1.9

Fixed error when setting initial pool prefab in the inspector.



1.1.8

Fixed bug with one LeanPool.Spawn overload.







Components

IPoolable

If you implement this interface in a component on your pooled prefab, then the OnSpawn and OnDespawn methods will be automatically called when the associated LeanGameObjectPool.Notification = PoolableInterface.



LeanClassPool<T>

This class allows you to pool normal C# classes, for example:

var foo = Lean.Pool.LeanClassPool.Spawn() ?? new Foo();

Lean.Pool.LeanClassPool.Despawn(foo);


static T
Spawn
System.Action<T> onSpawn

This will either return a pooled class instance, or null. If an instance it found, onSpawn will be called with it. NOTE: onSpawn is expected to not be null.



static T
Spawn
System.Predicate<T> match

This will either return a pooled class instance, or null.

All pooled classes will be checked with match to see if they qualify.

NOTE  match is expected to not be null.


static T
Spawn
System.Predicate<T> match, System.Action<T> onSpawn

This will either return a pooled class instance, or null.

All pooled classes will be checked with match to see if they qualify.

If an instance it found, onSpawn will be called with it.

NOTE  match is expected to not be null.
NOTE  onSpawn is expected to not be null.


static void
Despawn
T instance

This will pool the passed class instance.



static void
Despawn
T instance, System.Action<T> onDespawn

This will pool the passed class instance.

If you need to perform despawning code then you can do that via onDespawn.




LeanGameObjectPool

This component allows you to pool GameObjects, giving you a very fast alternative to Instantiate and Destroy.

Pools also have settings to preload, recycle, and set the spawn capacity, giving you lots of control over your spawning.


static LinkedList<LeanGameObjectPool>
Instances

All active and enabled pools in the scene.



GameObject
Prefab

The prefab this pool controls.



NotificationType
Notification

If you need to perform a special action when a prefab is spawned or despawned, then this allows you to control how that action is performed.

None If you use this then you must rely on the OnEnable and OnDisable messages.
SendMessage The prefab clone is sent the OnSpawn and OnDespawn messages.
BroadcastMessage The prefab clone and all its children are sent the OnSpawn and OnDespawn messages.
IPoolable The prefab clone's components implementing IPoolable are called.
Broadcast IPoolable The prefab clone and all its child components implementing IPoolable are called.


StrategyType
Strategy

This allows you to control how spawned/despawned GameObjects will be handled. The DeactivateViaHierarchy mode should be used if you need to maintain your prefab's de/activation state.

ActivateAndDeactivate = Despawned clones will be deactivated and placed under this GameObject.

DeactivateViaHierarchy = Despawned clones will be placed under a deactivated GameObject and left alone.



int
Preload

Should this pool preload some clones?



int
Capacity

Should this pool have a maximum amount of spawnable clones?



bool
Recycle

If the pool reaches capacity, should new spawns force older ones to despawn?



bool
Persist

Should this pool be marked as DontDestroyOnLoad?



bool
Stamp

Should the spawned clones have their clone index appended to their name?



bool
Warnings

Should detected issues be output to the console?



Transform
DeactivatedChild

If you're using the Strategy = DeactivateViaHierarchy mode, then all despawned clones will be placed under this.



bool
DespawnedClonesMatch

This will return false if you have preloaded prefabs do not match the Prefab.

NOTE  This is only available in the editor.


int
Spawned

Returns the amount of spawned clones.



int
Despawned

Returns the amount of despawned clones.



int
Total

Returns the total amount of spawned and despawned clones.



static bool
TryFindPoolByPrefab
GameObject prefab, ref LeanGameObjectPool foundPool

Find the pool responsible for handling the specified prefab.



static bool
TryFindPoolByClone
GameObject clone, ref LeanGameObjectPool pool

Find the pool responsible for handling the specified prefab clone.

NOTE  This can be an expensive operation if you have many large pools.


void
Spawn

This will either spawn a previously despawned/preloaded clone, recycle one, create a new one, or return null.

NOTE  This method is designed to work with Unity's event system, so it has no return value.


void
Spawn
Vector3 position

This will either spawn a previously despawned/preloaded clone, recycle one, create a new one, or return null.

NOTE  This method is designed to work with Unity's event system, so it has no return value.


GameObject
Spawn
Transform parent, bool worldPositionStays = false

This will either spawn a previously despawned/preloaded clone, recycle one, create a new one, or return null.



GameObject
Spawn
Vector3 position, Quaternion rotation, Transform parent = null

This will either spawn a previously despawned/preloaded clone, recycle one, create a new one, or return null.



bool
TrySpawn
ref GameObject clone, Transform parent, bool worldPositionStays = false

This will either spawn a previously despawned/preloaded clone, recycle one, create a new one, or return null.



bool
TrySpawn
ref GameObject clone, Vector3 position, Quaternion rotation, Transform parent = null

This will either spawn a previously despawned/preloaded clone, recycle one, create a new one, or return null.



bool
TrySpawn
ref GameObject clone

This will either spawn a previously despawned/preloaded clone, recycle one, create a new one, or return null.



bool
TrySpawn
ref GameObject clone, Vector3 localPosition, Quaternion localRotation, Vector3 localScale, Transform parent, bool worldPositionStays

This will either spawn a previously despawned/preloaded clone, recycle one, create a new one, or return null.



void
DespawnOldest

This will despawn the oldest prefab clone that is still spawned.



void
DespawnAll
bool cleanLinks

This method will despawn all currently spawned prefabs managed by this pool.

NOTE  If this pool's prefabs were spawned using LeanPool.Spawn, then cleanLinks should be set to true.


void
Despawn
GameObject clone, float t = 0.0f

This will either instantly despawn the specified gameObject, or delay despawn it after t seconds.



void
Detach
GameObject clone, bool cleanLinks = true

This allows you to remove all references to the specified clone from this pool.

A detached clone will act as a normal GameObject, requiring you to manually destroy or otherwise manage it.

NOTE  If this clone has been despawned then it will still be parented to the pool.
NOTE  If this pool's prefabs were spawned using LeanPool.Spawn, then cleanLinks should be set to true.


void
PreloadOneMore

This method will create an additional prefab clone and add it to the despawned list.



void
PreloadAll

This will preload the pool based on the Preload setting.



void
Clean

This will destroy all preloaded or despawned clones. This is useful if you've despawned more prefabs than you likely need, and want to free up some memory.



void
GetClones
List<GameObject> gameObjects, bool addSpawnedClones = true, bool addDespawnedClones = true

This method will clear and fill the specified list with the specified clones from this pool.




LeanPool

This class handles the association between a spawned prefab, and the LeanGameObjectPool component that manages it.


static Dictionary<GameObject, LeanGameObjectPool>
Links

When you spawn a prefab from this class, the association between the spawned clone and the pool that spawned it will be stored here so it can quickly be despawned.



static T
Spawn<T>
T prefab, Transform parent, bool worldPositionStays = false

This allows you to spawn a prefab via Component.



static T
Spawn<T>
T prefab, Vector3 position, Quaternion rotation, Transform parent = null

This allows you to spawn a prefab via Component.



static T
Spawn<T>
T prefab

This allows you to spawn a prefab via Component.



static GameObject
Spawn
GameObject prefab, Transform parent, bool worldPositionStays = false

This allows you to spawn a prefab via GameObject.



static GameObject
Spawn
GameObject prefab, Vector3 position, Quaternion rotation, Transform parent = null

This allows you to spawn a prefab via GameObject.



static GameObject
Spawn
GameObject prefab

This allows you to spawn a prefab via GameObject.



static void
DespawnAll

This will call DespawnAll on all active and enabled pools.



static void
Despawn
Component clone, float delay = 0.0f

This allows you to despawn a clone via Component, with optional delay.



static void
Despawn
GameObject clone, float delay = 0.0f

This allows you to despawn a clone via GameObject, with optional delay.



static void
Detach
Component clone, bool detachFromPool = true

This allows you to detach a clone via Component.

A detached clone will act as a normal GameObject, requiring you to manually destroy or otherwise manage it.

NOTE  If this clone has been despawned then it will still be parented to the pool.


static void
Detach
GameObject clone, bool detachFromPool

This allows you to detach a clone via GameObject.

A detached clone will act as a normal GameObject, requiring you to manually destroy or otherwise manage it.

NOTE  If this clone has been despawned then it will still be parented to the pool.



LeanPoolDebugger

This component can be added to your prefab GameObject, and it will throw warnings if it is instantiated without the use of LeanPool.Spawn, or despawned without the use of LeanPool.Despawn.



LeanPooledRigidbody

This component allows you to reset a Rigidbody's velocity via Messages or via Poolable.



LeanPooledRigidbody2D

This component will automatically reset a Rigidbody2D when it gets spawned/despawned.



Index

What is Lean Pool?

How do I use it?

Why do I have to type Lean.Pool. before everything?

How do I alter the settings?

My Rigidbody velocity isn't being reset!?

How do I write custom spawning/despawning code?

How do I increase the performance even more?

Why do I get warnings in the console?



Assets

Lean Touch

Lean Touch+

Lean Localization

Lean Pool

Lean Transition

Lean GUI

Lean GUI Shapes

Lean Texture

Lean Texture+

Spaceships - Build & Destroy

Modular Backgrounds

Paint in 3D

Paint in 2D

Paint in Editor

FLOW

Destructible 2D

Space Graphics Toolkit

Space Graphics Planets

Volumetric Audio



Versions

2.1.0

2.0.2

2.0.1

2.0.0

1.4.3

1.4.2

1.4.1

1.4.0

1.3.2

1.3.1

1.3.0

1.2.9

1.2.8

1.2.7

1.2.6

1.2.5

1.2.4

1.2.3

1.2.2

1.2.1

1.2.0

1.1.9

1.1.8



Components

IPoolable

LeanClassPool<T>

LeanGameObjectPool

LeanPool

LeanPoolDebugger

LeanPooledRigidbody

LeanPooledRigidbody2D