2. Per-Prefab Options

This section will look at the options and features available per-prefab (PrefabPool). These are optional and only need to be used if you want to take advantage of one or more of these features. It is highly recommended that you use preload to load at least 1 instance at the start of your game to allow Unity to load all the references and other information/caching before game-play begins.

This tutorial will pick up where 1. Start Pooling! left off and show you how to pre-load some instances. It will then explore the rest of the features available should you need them for your game.

The PoolManager Inspector Interface Overview

Pre-loading Instances

Expand Per Pefab Pool Options, set the size to (at least)1 and drag&drop a prefab in to the Prefab field. Also set the Preload Amount to 1 or more. I chose 10.

(For this tutorial, you can use any prefab, even one containing just an empty game object.)

Now play the game and you will see 10 instances pre-loaded. That's it!

Pre-loading Over-Time

In some situations it may be desirable to preload large amounts of items by spreading them out over the course of several frames, to reduce the load in each frame. In the example image to the right, 50 instances will be preloaded over 6 frames, after waiting 1.25 seconds to begin. This is just an example. In reality, 50 instances may be fine to preload in a single frame by leaving the "Preload Time" check box off.

Items of Interest in the Scene Hierarchy

Notice the instance names are light gray. This is because they are not active. When SpawnPool.Spawn() is used on the "Shapes" SpawnPool, one of these instances will be spawned (made active) rather than creating a whole new instance.

Also note the names have numbers appended to them and they are all children of an empty GameObject with the same name as the Pool. These are two of PoolManagers organizational features to help make your development-life easier. This extra empty GameObject should have no measurable impact on your games performance or memory usage.

A SpawnPool is PoolManager's primary Pool structure. A SpawnPool can have more than one PrefabPool. To add PrefabPools to a SpawnPool, just increase the Size under Per Prefab Pool Options. Each PrefabPool can have different settings, such as a different number of pre-loaded instances, or any other option. This means you have fine-grain control over your instances but the logical organizational benefits of archetype pools (e.g. many enemies in one "Enemies" pool or many different explosion prefabs in one "Explosions" pool)

Other Per-Prefab Options

Limit Instances

Turn ON 'Limit Instances' to limit the number of instances allowed in the game. Turning this ON means that when 'Limit Amount' is hit, no more instances will be created. (Calls to SpawnPool.Spawn() will do nothing and will return null. This is the only time SpawnPool.Spawn() will return null.) This can be good for non-critical objects like bullets or explosion Flares. You would never want to use this for enemies, for example, unless it makes sense to begin ignoring enemy spawns in the context of your game.

Limit FIFO

With this option on, the number of instances will still be limited, but instead of stopping spawns and returning null, PoolManager will continue to spawn new instances by first despawning old ones. The instance is chosen on a First-In-First-Out (FIFO) basis.

Instance Culling

Turn ON 'Cull Despawned' to activate the culling feature for this SpawnPool which will remove de-spawned (inactive) instances from the pool if the size of the pool grows too large (set by 'Cull Above').

This should only be used in extreme cases for memory management. If the number of instances in your scene is not causing memory issues, do not use this feature. For most pools (or games for that matter), it is better to leave this off as memory is more plentiful than performance and de-spawned (inactive) instances shouldn't affect performance at all. If you do need this feature, you should fine-tune how often this is triggered to target extreme events.

A good example of when to use this would be if you you are Pooling projectiles and usually never need more than 10 at a time, but then there is a big one-off fire-fight where 50 projectiles are needed. Rather than keep the extra 40 around in memory from then on, set the 'Cull Above' property to 15 (well above the expected max) and the Pool will Destroy() the extra instances from the game to free up the memory.

A lot of effort has gone in to making this feature smart to keep your game running smoothly...

Culling only destroys de-spawned items, so, once triggered, it will automatically wait for items to despawn before doing anything, and will continue to run until the 'Cull Above' number is reached. However, you wouldn't want this culling feature to be fighting the Pool during the extreme event, causing extra Instantiate() and Destroy() calls. This is why 'Cull Delay' is provided. Set this to delay the culling for a reasonable time. This is also the amount of time that will pass between checks for de-spawned items to cull, so don't set it too high either or it will take a long time to cull everything. When the check occurs, more than one instance may be culled though, so there is no need to set this to check too often either.

For example, if I set 'Cull Delay' to 30 (seconds) and 'Cull Above' to 50... once the number of instances reaches 50, PoolManager will wait 30 seconds and start a co-routine that will check every 30 seconds for de-spawned unstances to cull untill the total number of instances remaining is below 50 again. Culling will then shut off.

Even if culling runs forever (if it is never able to reduce the number of instances to the 'Cull Above' amount), it should not have a measurable effect on your game's performance. This is a very "cheap" check.

'Cull Max Per Pass' is the maximum number of instances that can be destroyed each time the culling check occurs. For example, if you set this to 5 and'Cull Delay' to 6, then every 6 seconds 5 de-spawned instances will be destroyed until 'Cull Above' is reached. This is a max value because if will destroy as many as possible but will destroy less if there aren't enough de-spawned instances ready for destruction or to finish at the amount set with 'Cull Above'. This is a great way to control how fast culling occurs. You may wish to set this at a high value and only reduce it if you experience a frame stutter when the culling check runs. Alternatively, because culling is process-cheep, you may wish to keep the value low and spread out the internal calls to Destroy(). Usage is very situational.

One last note: Culling is triggered during SpawnPool.Despawn(), so if you are only spawning when 'Cull Above' is passed, 'Cull Delay' will not start counting until the first instance is de-spawned. This is desirable for two reasons. First, if there is nothing de-spawned then there is nothing for culling to do anyway, and second, to reinforce the passive nature of this feature. Culling should be as simple and effective and should help avoid the issues generally associated with destroying lots of objects in a short amount of time. Culling spreads it out.