The Challenge

In my university Tower Defence game project, I faced the challenge of efficiently spawning large numbers of enemies and projectiles without causing performance drops. The solution was to implement an object pooling system that would reuse game objects instead of constantly creating and destroying them.

The video above demonstrates my object pooling script in action. It allows me to easily pool and unpool objects by an ID, significantly improving performance for frequently spawned objects like bullets and enemies.

Implementation

Here's an example of the code needed to retrieve an object from the pool:

GameObject curBullet = objectPooler.curObjectPooler.getObject(ID);

if (curBullet == null)
curBullet = Instantiate(PREFAB);

Data Structure

The object pool is stored in a data structure that allows for multiple objects with the same ID, making it possible to have multiple "bullets" with the same identifier but as different instances:

public List<KeyValuePair<string, GameObject>> objectPool;

Challenges Encountered

While the solution greatly improved performance, it wasn't without issues. One significant problem was that objects weren't properly resetting to their default state when returned to the pool, resulting in enemies sometimes spawning with incorrect health values or the wrong class properties. This led to some interesting and unexpected behaviours:

Benefits

Despite these challenges, the object pooling system significantly improved performance, allowing me to spawn large numbers of enemies and projectiles with minimal impact on frame rate. This was a crucial optimisation for maintaining smooth gameplay, especially in multiplayer scenarios where networking adds additional overhead.

Key Lessons

Through implementing this system, I learned valuable lessons about:

  • Memory management in game development
  • The importance of proper object state management
  • Performance optimisation for real-time multiplayer games
  • Debugging complex object behaviour in networked environments