Unity: Prefactory (A Better Pool Manager)
UPDATE: Okay, so I have to apologise to @gl33mer, as I made a mistake in my instructions! The updated instructions are below. The correct call to Spawn/Despawn does not use the PoolManager.Instance object reference, as both Spawn and Despawn are static methods, not instance methods. Sorry! Also, I've uploaded a small demo package where a sphere/cube are spawned every other second (intermittently). See blow for the link.
At the request of fellow tweeterer @gl33mer, I've uploaded my Unity pool manager component, Prefactory v1.0. I have to confess that I haven't done a great deal of stability testing with it, but I haven't had any problems with it either (and I've used it quite extensively in tests and in the few games I've published to the blog). It's fast and flexible, and hopefully of use to others. I'm working on adding extra functionality, such as string-based construction of game entities (something which would be super handy for my next little adventure) and I'll be sure to post an update when and if one is completed.
A better set of instructions than this blathering mess of a blog post would help, too. I'll see what I can do...
For the record, Prefactory v1.0 is completely free to use however you like. You don't need to credit me or anything. I don't care if you modify it, use it commercially, or get down and dirty with it (although I would be morbidly curious about how one does that with code, exactly).
A short message letting me know you're using it in something awesome would totally make my egotistical day, but that's totally optional
To use Prefactory v1.0:
1. Assign the PoolObject MonoBehaviour to any GameObject/Prefab you wish to pool. For PoolObjects, the following options are available:

Prefab Name: Must be filled in, and must be unique per poolable object. This is the name that the PoolManager uses to manage the object.
Is Dynamic: If true, the PoolObject's children will NOT be cached for enabling/disabling of GameObjects and renderers. Set this to true if the PoolObject's hierarchy will change.
You can trigger a PoolObject to auto-despawn with the PoolObject.DespawnAfterSeconds(float seconds) method, or a coroutine method CRDespawnAfterSeconds(float seconds) which will yield after the object is despawned.
PoolObject.Age is a float property with the PoolObject's age in seconds since last being spawned, while PoolObject.AgeAsScalar will return a normalized 0 - 1 float for any PoolObject which has had an auto-despawn triggered.
2. Create a new GameObject and assign it the PoolManager MonoBehaviour. Drag and drop PoolObjects onto the PoolManager's inspector as shown below:

The pool settings for each PoolObject appear as a collapsible roll-out, and are as follows:

Pre-Allocate: The number of PoolObject instances to create at level load.
Allocate Block: The number of new PoolObject instances to create when the pool becomes empty.
Hard Limit: If true, the PoolManager will return null once the spawn limit has been reached.
Limit: The spawn limit when Hard Limit is on.
Cull: If true, excess PoolObjects will be destroyed.
Cull Above: Any excess PoolObjects exceeding this count when Cull is on, will be destroyed.
Cull Delay: The time between culls, in seconds.
3. To get an instance from the PoolManager:
PoolManager.Spawn("prefabName");
// or
PoolManager.Spawn(GameObject instanceOfPrefabToSpawn);
4. To despawn an instance back to the PoolManager:
PoolManager.Despawn(GameObject prefabInstanceToDespawn);
That's all there is to it (LOL). It's not the world's most intuitive system, but it works! So there you go @gl33mer, I hope it comes in useful. And make sure you send me a link to your game when it's done!
March 17th, 2012 - 18:42
Thank you
works perfectly.
March 17th, 2012 - 18:49
No problems! Glad it works
March 27th, 2012 - 21:54
Thank you.
June 6th, 2012 - 02:51
Very cool. This is most handy on portables (iPhone, Android, Tablet etc.) where instantiation and the Garbage Collector can slow a game down to a crawl. Not any more though.
A mighty thanks for this!
June 6th, 2012 - 11:01
You’re welcome! Thanks for leaving a message
August 3rd, 2012 - 13:23
Awesome tool, thanks so much for making it. I tried using another pool manager, it didn’t work out as well. It’ll be spawning bullets, zombies, and explosions in my soon to be released game: It’s Raining Zombies( http://itsrainingzombies.blogspot.com )
Thanks so much again
August 4th, 2012 - 10:25
No problems, I’m glad someone could make use of it! Good luck with your game, it looks like a bunch of fun
August 6th, 2012 - 09:23
Hey me again, slight hiccup here. When I reload a scene (with application.loadlevel) that has instantiated pool objects, the pooled objects are all gone and there is an error that comes up. Just me?
I can circumvent this problem by requiring the player to exit the entire app and then restart the level.
August 24th, 2012 - 13:38
I have exactly the same problem. When I reload a level, there’s an exception
ArgumentException: An element with the same key already exists in the dictionary.
System.Collections.Generic.Dictionary`2[System.String,PrefabPool].Add (System.String key, .PrefabPool value)
PoolManager.InitializePrefabPools () (at Assets/Managers/Prefactory/_scripts/PoolManager.cs:66)
PoolManager.Awake () (at Assets/Managers/Prefactory/_scripts/PoolManager.cs:48)
How can I solve this?
August 28th, 2012 - 20:22
Sorry I’m only just replying, since I moved my blog I no longer get email notifications for comments.
“How can I solve this?”
Good question! I have no idea! It’s been too long since I’ve looked at this code, but I’ll check it out when I get a chance and get back to you.
Do either of you have the PoolManager script added to a persistent object marked as DontDestroyOnLoad()?
Actually, it’s probably because the PoolManager uses a static Dictionary to store the object pools. I shall update it and post a follow up comment when it’s done!
August 28th, 2012 - 20:37
Okay I’ve done a quick update, adding an event to clear the existing pools when a level is loaded. I hope it works!
September 28th, 2012 - 22:38
Ow! I feel so stupid now! I made my own Pool Manager a while ago, and now I’ve being working on a V2 version since a while, but if I had noticed your plugin (actually, I noticed it, but forgot about when I needed a pool manager) I might’ve gone with that from the beginning!
Anyway, too late now, I’ll finish what I started (I’m actually shedding blood on the Editor part, so that enums are automatically created for each pool – but at least I’m taking the chance to build an internal UnityEditor helper assembly
).
September 28th, 2012 - 23:42
Awesome! That sounds much cooler than this crappy thing
Will you be releasing it on the asset store?
September 29th, 2012 - 20:09
Your thing looks awesome!
And yes, I’m shedding blood on the editor part (while the runtime thingies are almost complete) to make it as usable as I can (plus adding other things I wanted, after using my first Pool Manager for a while, like UnitPoolCollections – which are not exactly pools, but can be used to spawn/unspawn a single instance), so I can try and release it as my first payed plugin on the Asset Store (though there’ll be free versions for you and every other developer I know – without any obligation to use it, obviously
).
By the way, a silly question. To unspawn instances I always used methods called Unspawn, while I noticed you’re using Despawn. Is that a specific/common naming for it, and as such I should change Unspawn to Despawn?
P.S. now I’m very curious to look at your code, but I promised myself I won’t. Since I plan to sell my pool manager, subconsciously (or consciously) stealing/being-inspired by parts of your code would be bad. But since I already saw the interface, can I steal your “Pre-allocate” label (way nicer than the “Startup Instances” I was using)?
September 29th, 2012 - 20:52
Despawn has always seemed the right word to me. Perhaps it is used elsewhere and I picked it up from another engine’s vernacular, or maybe it just popped into conversation one day and sounded right? Who knows! I think both ‘despawn’ and ‘unspawn’ would be acceptible, but ‘unspawn’ does sound a little awkward to me.
EDIT: After a little browsing, the Unreal engine does refer to it as despawning. Take that as you will!
As for looking at my code or using terminology that I’ve used, please, go for it. I hardly think you’re the kind of person who’d just box up someone else’s code and sell it, and at any rate, it’s not very complex so it’d be strange if we didn’t have more or less the same code in place.
Besides, how can I say no when I know you’re going to make something better?!
September 29th, 2012 - 21:22
Thanks Boon, you’re always so nice
I’m definitely going with Despawn then, thanks for the additional infos (I was already convinced when you said it sounded awkward to you), and with stealing your “Pre-allocate” label.
So I’ll still restrain from looking at your code at least until I finish everything, and maybe do something worse, but with a bloodshed UI
About the code, you’re right that probably we have more or less the same stuff in there, but I’m a man of principles!
P.S. I suppose you missed my direct message on Twitter a while ago. Bins developer gave me some free licenses from friends. You want one (works on Win7/8 only)?
September 29th, 2012 - 21:53
Sure man that looks great! Thanks!
September 30th, 2012 - 19:18
Sent you the Bins stuff as a message on Unity’s forums
October 16th, 2012 - 02:05
Hey, looks great and the price tag is unbeatable.
Going to test this right away. Thanks a lot for sharing.
November 25th, 2012 - 04:44
Hey I just upgraded to Unity 4.0 and I seem to be getting this weird error:
NullReferenceException: Object reference not set to an instance of an object
PoolObject.SetActive (Boolean active) (at Assets/Standard Assets/Prefactory/scripts/PoolObject.cs:156)
On this line: foreach(GameObject go in GameObjectCache){
I tried adding some debug.log statements, the GameObjectCache seems to be adding objects just fine. I readded the PoolObject scripts to the objects and readded them to the PoolManager. I have no idea why I would be getting a null object.
Any ideas?
December 10th, 2012 - 13:12
Sorry Jason, no idea
I’m tied up in another project at the moment and all of my Unity stuff is buried away somewhere. If I can find some time, I’ll upgrade to 4.0 and have a go at troubleshooting this. Apologies for the late reply!
February 26th, 2013 - 08:20
Hi, If u could fix that problem would be great. Tool is great but it shoud work propertly on Unity 4.0
Great Job!
February 27th, 2013 - 14:31
Honestly, I don’t think I’m likely to get around to it any time soon. I wish I could help, but I’m flat out with commitments that make scripting wishful thinking right now. Feel free to mess with the source code and change it how you like (of course). It’s not very complex, there’s a few basic classes. Best of luck!
November 29th, 2012 - 16:24
Hi,
Unity (the ‘new’ 4) gives warnings when using pool manager in the editor, there are missing layout ‘closures’ in PoolManagerEditor.cc Ln 214:
GUILayout.EndVertical();
GUILayout.EndHorizontal();
thanks for this btw!
December 10th, 2012 - 13:13
No problems! I wish I could solve the bug for you, but I’m out of commission for a while unfortunately. If I can find some spare time to upgrade to 4.0 and trouble-shoot this, I’ll update the blog post with new links. Thanks for downloading, and sorry for the slow response!
December 16th, 2012 - 06:04
Hi, they are just warnings, no rush
it happens when dragging prefab onto manager, unity spits quite few of them into console, but otherwise it seems to be fine
January 21st, 2013 - 18:49
For those of you new to optimization (probably for mobile). I came back here to share this little tidbit from the Unity documentation which is relevant to object pools. They’re not always the more performant option.
Here’s the quote (from here:http://docs.unity3d.com/Documentation/Manual/iphone-PracticalScriptingOptimizations.html#Object%20Pooling%20Example):
“Why Object Pooling can be Slower
One issue is that the creation of a pool reduces the amount of heap memory available for other purposes; so if you keep allocating memory on top of the pools you just created, you might trigger garbage collection even more often. Not only that, every collection will be slower, because the time taken for a collection increases with the number of live objects. With these issues in mind, it should be apparent that performance will suffer if you allocate pools that are too large or keep them active when the objects they contain will not be needed for some time. Furthermore, many types of objects don’t lend themselves well to object pooling. For example, the game may include spell effects that persist for a considerable time or enemies that appear in large numbers but which are only killed gradually as the game progresses. In such cases, the performance overhead of an object pool greatly outweighs the benefits and so it should not be used. ”
Hope it’s ok I posted this here Boon. I had a feeling it could save some peoples frustrations in the longer run.
January 23rd, 2013 - 16:16
Thanks for the excellent response, gl33mer! Knowing when (and how, and how not) to optimise is an incredibly important skill set. This is new info to me, too, so I appreciate you sharing it!
January 29th, 2013 - 09:48
Can any one help me to call the:
3. To get an instance from the PoolManager:
PoolManager.Spawn(“prefabName”);
// or
PoolManager.Spawn(GameObject instanceOfPrefabToSpawn);
4. To despawn an instance back to the PoolManager:
PoolManager.Despawn(GameObject prefabInstanceToDespawn);
in java?
I have the 3 C# scripts form prefactry folder in the Plugins folder(will be compiled first)
now when trying to call the
PoolManager.Spawn(GameObject instanceOfPrefabToSpawn);
And
PoolManager.Despawn(GameObject prefabInstanceToDespawn);
It gives me tese errors:
Assets/TopdownMobile/Script/DestroyBulletNew.js(6,38): BCE0044: expecting ), found ‘instanceOfPrefabToSpawn’.
Assets/TopdownMobile/Script/DestroyBulletNew.js(6,61): BCE0043: Unexpected token: ).
im clueles =\ really want to use this pool script as the others give me headaches.
)
(im a graphical designer not a coder
January 29th, 2013 - 13:21
I’m afraid I can’t help without seeing your code. Maybe you could try posting on the Unity forums, as it sounds like a problem with your script formatting. I could be wrong of course. Sorry to not be much help!
January 31st, 2013 - 07:58
var lifeTime : int = 2;
//private var csScript : PoolManager;
//var csScript : PoolManager;
function Awake() {
if(lifeTime <= 0)
Despawn();
//csScript = this.GetComponent("PoolManager");
//csScript = GetComponentInChildren(PoolManager);
//Destroy(gameObject, lifeTime);
//script = GetComponentInChildren(PoolManager);
//script.DoSomething ();
//PoolManager.Despawn(GameObject prefabInstanceToDespawn);
//Despawn(GameObject prefabInstanceToDespawn);
//}
}
function Despawn()
{
PoolManager.Despawn(gameObject);
}
i have no errors now,but havent tested it yet(whats comented out didnt work).
i know the scrippts have a timer it self,but i need this working for a different reason.
January 31st, 2013 - 07:59
ohh,the destroy was comented oud cuz that was part of the old code
January 31st, 2013 - 08:47
Pfff so it wont despawn the prefab.
it seems that the code PoolManager.Despawn(gameObject); doesnt do any thing? putting GameObject or this.gameobject also doesnt work.
January 31st, 2013 - 09:37
oke,got it working(the despawning part) here is the code.
private var nonsense : float = 0.0;
var thisdoesnothign : float = 0;
var DespawnDelay = 0.0;
function Awake() {
}
function Start(){
}
function Update(){
thisdoesnothign += Time.deltaTime;
if (thisdoesnothign >= DespawnDelay){
thisdoesnothign = 0;
if(nonsense > 0){
Debug.Log(“nonsense”);
} else{
PoolManager.Despawn(gameObject);}
}
}
now i have a problem. idk how to shoot the damn thing xp.(its a bullet)
here is the code.
public var bulletPrefab : Transform;
public var bulletSpeed : float = 6000;
var ShotDelay = 5.0;
var timer : float = 0;
var rotateJoystick : Joystick;
function Update(){
if (rotateJoystick.IsFingerDown()){
timer += Time.deltaTime;
if (timer >= ShotDelay){
timer = 0;
if(!bulletPrefab || !bulletSpeed){
Debug.Log(“[shoot] ‘bulletPrefab’ or ‘bulletSpeed’ is undefined”);
} else{
var bulletCreate = Instantiate(, GameObject.Find(“BSpawnPoint”).transform.position, Quaternion.identity);
bulletCreate.rigidbody.AddForce(transform.forward * bulletSpeed);
//PoolManager.Spawn(“Bullet”).rigidbody.AddForce(transform.forward * bulletSpeed); <—Works but does not shoot from gameobject"BSpawnPoint.
}
}
}
}
function Spawn()
{
PoolManager.Spawn("Bullet");
}
January 31st, 2013 - 09:41
** var bulletCreate = Instantiate(bulletPrefab,
Bulletprefab was missing in the upper message.
January 31st, 2013 - 10:06
These questions are outside the scope of my blog. I’m not all that clued on javascript for starters, but anything not related to the PoolManager will be better asked over at the Unity forums. Good luck!
January 29th, 2013 - 12:59
Thank you so much! I was in the middle of building my own (which I really didn’t want to do) when I found this. I am building a bullet hell shot library and this is really handy! Had it up and running in 5 minutes! Thank you and great work.
March 31st, 2013 - 08:53
You, sir, are awesome!
Thank you for this!
April 3rd, 2013 - 08:17
Thank you!