Unity 2021 Object Pooling
The awesome ease of its use…and its pitfalls
What are Object Pools?
Every time the user presses the Space bar (or mouse click, whatever) the game creates a bullet (laser in my case) that moves up and out of the game. Every time the laser hits an enemy or leaves the screen, you need to destroy it (otherwise it lives forever in the game memory, slowing the game down until you quit, going off in the uncharted wilds of game space…)
That’s a lot of creations and destructions, and a lot of effort on the part of the game engine. What for, after all? We won’t have more than …20 bullets on screen at once? Why not just create 20, move them around and make them appear and disappear instead?
That, my friends, is an object pool. You create a “pool” of the object, in this case a group of premade lasers; they are all inactive. When you need one, you bring it where you want and activate it; when you don’t need it anymore, you deactivate it and return it to the pool.
Great, how do I use it?
There are many options to do this yourself, but Unity 2021 comes with built-in object pools (here’s the awesome tutorial by GameDev Guru). I was using Unity 2019, but I am firmly against re-inventing the wheel. Why should I create my own object pool when Unity has already done and debugged it for me?
So I upgraded to Unity 2021 (it went smoothly, my game really isn’t that complicated yet) and was instantly charmed by the amazing ease of use. In my game manager, in Awake (or Start) I create my object pool:
Of course, I need to remember to drag my laser prefab into the the script, not a problem (not that I ever forgot …er, never mind).
Then in my Player script (that creates the lasers when pressing space bar) I swapped the existing code:
With this simple code:
And I do the opposite when destroying the object (in my LaserController), from this:
Piece of cake! Let’s play:
Wait, what just happened here?
My player…just created an enemy laser instead of a player laser and shot itself!?
How did this happen?
I’m sure that you sharp-eyed readers have already seen the massive error I did above. But I didn’t. I was sure there was something wrong with my instantiation function. Or maybe the fact that the enemy laser was a variant of player laser? I read up in the unity forums and anywhere I could find, and only after reading this (sadly some time after reading it, but good enough) I realized that…
The pool has no way of knowing if a returned object was created using the pool or not.
So when I return an object to the pool I need to be sure I am returning the right thing…and I wasn’t. Look again at the new-destroy-method above. I return the laser to the pool if it’s offscreen, both if it’s too high…or too low. In other words, I was putting the *enemy* lasers back in the pool in addition to the player lasers.
Once I fixed this, everything worked smoothly.
So… Object pools in Unity 2021 are really easy to use. It was a few lines of code, pretty much no brainers. But be careful! If you find your pool creating objects that aren’t supposed to be there, maybe, just maybe, you put them there. Just saying.
I’m off to shoot some aliens :)