Networked object pool example for UNet HLAPI

Attached is an example of networked object pool for UNet. It uses custom spawn handler functions and has object pools on the host and clients.

Instances of the specified “Prefab” object are created at initialization time, and then used when spawn messages are recieved, so there is no run-time object allocation and destruction.

The pooled object are controlled by the server. Example usage in a player script:

using UnityEngine;
using UnityEngine.Networking;

public class PlayerMove : NetworkBehaviour
{

    public NetworkSpawnPool bulletPool;

    void Start()
    {
        bulletPool = NetworkSpawnPool.GetPoolByName("DynamicPool");
    }
    //public GameObject bulletPrefab;

    public override void OnStartLocalPlayer()
    {
        GetComponent<MeshRenderer>().material.color = Color.red;
    }

    [Command]
    void CmdFire()
    {

        var bullet = bulletPool.ServerCreateFromPool(transform.position - transform.forward, Quaternion.identity);
        if (bullet == null)
            return;

        bullet.GetComponent<Rigidbody>().velocity = -transform.forward*4;
      
        // spawn the bullet on the clients
        NetworkServer.Spawn(bullet);

        bulletPool.ServerReturnToPool(bullet, 2.0f);
    }

    void Update()
    {
        if (!isLocalPlayer)
            return;

        var x = Input.GetAxis("Horizontal")*0.1f;
        var z = Input.GetAxis("Vertical")*0.1f;

        transform.Translate(x, 0, z);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            // Command function is called on the client, but invoked on the server
            CmdFire();
        }
    }
}

Although by default it works with prefabs, there is a virtual function that can be overridden to construct objects from code, like this below:

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class DynamicBulletPool : NetworkSpawnPool {
   
    protected override GameObject InstantiatePrefab(Vector3 pos, Quaternion rot)
    {
        var go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        go.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
        go.transform.position = pos;
        go.transform.rotation = rot;
        var rb = go.AddComponent<Rigidbody>();
        rb.useGravity = false;
        go.AddComponent<NetworkIdentity>();
        go.AddComponent<NetworkTransform>();
        go.AddComponent<Bullet>();

        return go;
    }
}

Spawning with prefabs uses the assetId from the prefab, but dynamically created assetIds can be used.

The attached project shows it in use.

2391174–162910–NetworkSpawnPool.cs (4.65 KB)
2391174–162911–networkspawnpool.zip (46.2 KB)

6 Likes

oh excellent. missed this, thanks!

Excellent indeed, I shall have a play with this later :slight_smile:

Thank you!

Thanks for this. However, I’ve experienced some issues with the example project. In my first try, I’ve used local host and 1 client (Unity 5.3) and I got some warnings and error messages on the client after some playing around and firing a lot, see attached screenshot. I think the warnings can be ignored, but what about the error?

Another situation that causes this error is when a host game is stopped (disconnected) while pooled objects are still issued to be returned. At the point when they actuall return, the server is no longer active. This does not seem to be a big deal by itself, but when a new hosted game is started afterwards, a missing reference exception is thrown. To reproduce, just start host, fire some bullets, stop host, and start again.

Also, the current implementation does not seem to work with scene transitions out-of-the-box. It would be very nice if you can extend the example so that it also features an offline and online scene use case, as this seems to be more like the common case.

2420294--165604--NetworkPool.JPG

looks like I posted the wrong version of this project and now I cant find the latest one.

From memory the Bullet.cs script should not call bulletPool.ServerReturnToPool() on the client, it should disable the bullet locally, (is “isServer” is not set).

For scene changes, it seems that putting the pool in the “online” scene works best, instead of having it in the offline scene.

I am having an issue where it doesn’t spawn the objects in the scene from the object pool if the objects are already in the scene when a client joins a game in progress, causing an error saying "Pool doesn’t contain " + go when the object gets unspawned.

Hi guys, thanks to your comments and other threads in the forums I was able to make my own implementation of a networking object pooling system.
I don’t know if my solution is totally valid but it works, check it out:
http://www.justjuank.com/network-object-pooling-for-unity3d/
Sorry if this is an old thread, just wanted to share it with you.

Juan

2 Likes

thanks for sharing~:roll_eyes::roll_eyes:

when I try you pooling project. the rigidbody velocity is not applied to the clients side. the bullet spawns but does not move forward. any help would be great