Network Object Pooling for Unity3D
Posted by Juan on February 19, 2016
I’ve been recently porting one of our games from UDK to Unity3D and since then I’ve been trying to find a good plugin for pooling objects in a multiplayer game. Sadly there’s none, so I decided to give it a go myself.
In some of our previous games I used the EZ Object Pools plugin by Kevin Somers which is very nice and simple to use. So I decided to base mine on the simplicity style of EZ Objects Pools.
This system is made for the new networking system of Unity3D known as UNET. It consists of two classes:
One class is called NHNetworkedPool and is supposed to be a container or manager for one pool of objects of the same type. This class is in charge of:
- Register the prefab template in the NetworkManager.
- Instantiating the initial objects of the pool.
- Manage the future creation of any instances of the prefab assigned to it.
The instances created by the NHNetworkedPool get a script added called NHNetworkedPoolObject, this way the NHNetworkedPool can keep a record of the objects it creates and communicate with them in any case.
NHNetworkedPoolObject contains methods for activating and deactivating the object in the network, this was very tricky and is the major difference with EZ Objects Pool since it’s based on activating and deactivating objects by using SetActive(true/false). I researched a lot trying to find a solution to this case in order to keep using EZ Objects Pool. But I found that SetActive will never sync in networked games, at least in the current version of Unity.
Soooo, I made some kind of work around as a solution, I created a method for activating and deactivating the object; these methods will enable or disable any monobehaviour, collider and renderer in the object with the exception of the NHNetworkedPoolObject and NetworkIdentity components. This is the key to keep the objects communicated between server and client.
When a method for activating or deactivating the object is called on the server, it enables or disables all of it’s components and makes an RPC call to the client version of it to do the same.
The other tricky thing was to make the prefab of the object spawn in the client with the script NHNetworkedPoolObject attached. Since this script is attached dynamically by the server when it instantiates the object, it was never replicated to the client.
This post shed some light on me when I read about the spawning handlers which allows you to register an event when an object is being spawned or unspawned on the client. I implemented these handlers in my NHNetworkedPool script and so I was able to create the prefab in the pool with the NHNetworkedPoolObject script added to it in the client side.
That´s it for how I managed to do the network pooling. Now let me show you some screenshots of it in action and how to use it:
- Download this package containing the scripts of the network pooling system.
- Install the package files in your project.
- Create your prefab object that you want to spawn with the pooling system.
- Create a NetworkManager in your scene.
- Create an empty game object and add the NHNetworkedPool component.
Now you can setup your pool with the prefab you want it to spawn on the Template variable, set the size of the pool you want to spawn initially in Poolsize.
You can check the Auto Resize option so it will grow in case your game is requesting more objects than expected initially (this is recommended).
Once you’re done setting up the pool, just get a reference to the NHNetworkedPool and call the InstantiateFromPool method which has the following signature:
bool InstantiateFromPool(Vector3 pos, Quaternion rot, out GameObject obj)
You have to pass the position, rotation and a GameObject reference to save the newly instantiated object which will be null if the function returns false, so be sure to check that first.
Now when you create instances of the prefab using the networked pool you will see how it grows like in this example:
Note that I only set it up for 2 instances but it grows as long as I instantiates more.
And because this is a networked pool, it will get replicated to the client like this:
Note this is just my own implementation of a network object pooling system and I haven’t fully tested it under heavy load, but since I didn’t need a full blast of crazy creation of objects it works for me.
Here you can download the example project so you can try it yourself (it was done with Unity 5.3.2f1).
I hope this will be useful for someone out there.
If you have any suggestions or comments about this go ahead 🙂