Bullet Pools in Unity

Hal Brooks
3 min readMar 6, 2022

Objective: Create a bullet pool to recycle bullets, improving performance.

Bullets are recycled from the Bullet Pool and new bullets added if needed.

First create a 3D object > capsule and add a script called Bullet to it, as shown below. Drag this object into the projects Prefab folder then delete this object from the hierarchy.

Bullet prefab.

The Bullet script is shown below. Within the OnEnable() method the HideBullet() method is invoked after 5 seconds. While waiting for the Invoke(), the bullet’s transform is translated upward. HideBullet() inactivates this game object.

Bullet script.

Create an empty game object named Pool_Manager and add a new script PoolManager. Add another empty game object to hold the bullets named Bullet_Pool. The PoolManager is a singleton and uses the private _instance as a reference to itself, using the public Instance variable to provide access to other scripts. The bulletPool is a list of GameObjects, which will be populated with the _bulletPrefab and placed within the _bulletContainer. Note that System.Linq namespace is used for this PoolManager.

Variable assignment in PoolManager script.

Both _bulletPrefab and _bulletContainer use SerializeField and are assigned as shown below in the Pool_Manager’s inspector.

Variable assignment in Pool_Manager.

The bulletPool list is assigned using the GenerateBullets() method, and initially creates 10 bullets using a for loop. Each bullet is instantiated, parented to the _bulletContainer, inactivated and added to the bulletPool list.

GenerateBullets method in PoolManager.

The FireBullet() method returns a GameObject from the bulletPool and requires Linq namespace. The bulletPool is first checked to see if any bullets are inactive, and if all bullets are in play then a new bullet is created with the above GenerateBullet() method. With a bullet now available, the FirstOrDefault bullet that is inactive is returned.

FireBullet method in PoolManager.

Bullets are actually fired by the Player from within void Update() using the code below. When the player presses the space key a a bullet from the PoolManager is assigned using the above FireBullet() method. The bullet is then activated and positioned in game.

An object pool requires the object like Bullet, a PoolManager and an object using the pool, such as Player. Recycling objects enhances performance by avoiding constant instantiation and destruction of game objects.