Search Unity

  1. We want you to join us at GDC this year! We've added new sessions to Unity Central, space is limited so sign up now!
    Dismiss Notice
  2. Unity 2017.3 has arrived! Read about it here.
    Dismiss Notice
  3. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  4. Tell us about your experience here and you’ll get early access to the 2018 Game Studios report + more goodies.
    Dismiss Notice
  5. Be the first to take a peek at upcoming 2D Animation Preview. Drop into the forum and check it out!
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Spawn a new GameObject to clients from server at runtime

Discussion in 'Multiplayer Networking' started by ElGuapo, Oct 27, 2016.

  1. ElGuapo


    Sep 27, 2016
    Hi All,

    I have successfully used UNET to spawn prefabs that were added to the network spawnable prefabs in the unity editor for clients and servers. However, I need a way to spawn randomized GameObjects at runtime. Is it possible to have my server generate new GameObjects at runtime, and then spawn those onto the clients?

    So far in the code below I've been able to override the default spawning behavior by registering a client side spawn handler. Now when a server spawn command is issued, the remote client receives it's own spawn command. I've used this to spawn a cube on the host's client and a different cube (in green) on the remote clients in the code below.

    Instead of spawning a different cube in green on the remote client(s), I need someway to recreate the server's GameObject. Is it possible to use the assetID that is passed to reach back to the server and get the GameObject somehow? Or can I access the server's registered spawnable prefabs and recreate it on the client? Does anyone have any other ideas?

    Code (csharp):
    2. public class TestEnemyManagerServer : NetworkBehaviour
    3. {
    4.     private bool isNextEnemySpawnEnabled = false;
    5.     private NetworkManager myNetMan;
    7.     void Start ()
    8.     {
    9.         myNetMan= GameObject.Find ("Network Manager").GetComponent<NetworkManager>();
    10.         //Server will start checking for new enemy spawn requests every 2 seconds
    11.         if (isServer) {
    12.             InvokeRepeating ("SpawnEnemies", 2f, 2f);
    13.         }
    14.     }
    15.     public void SetNextEnemySpawnEnabled()
    16.     {
    17.         if (isServer) {
    18.             Debug.Log ("Server enabled next enemy spawn");
    19.             isNextEnemySpawnEnabled = true;
    20.         }
    21.     }
    23.     void SpawnEnemies()
    24.     {
    25.         if (isServer) {
    26.             if (isNextEnemySpawnEnabled) {
    27.                 Debug.Log ("Server preparing to spawn new enemy at runtime");
    28.                 GameObject theCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
    29.                 theCube.transform.position = new Vector3 (0, 2, 0);
    30.                 theCube.AddComponent<NetworkIdentity> ();
    32.                 //Generate a new unique assetId here - not currently unique
    33.                 NetworkHash128 myAssetId = NetworkHash128.Parse("e2656f");
    35.                 //Add to the registered spawnable prefabs for network spawning
    36.                 myNetMan.spawnPrefabs.Add(theCube);
    38.                 //Call the client to register the spawn handler via RPC
    39.                 RpcLoadPrefab (myAssetId);
    41.                 Debug.Log ("Server spawning object across clients");
    42.                 NetworkServer.Spawn(theCube,myAssetId);
    44.                 //Set trigger bool back to false
    45.                 isNextEnemySpawnEnabled = false;
    46.             }
    47.         }
    48.     }
    50.     [ClientRpc]
    51.     void RpcLoadPrefab(NetworkHash128 assetId)
    52.     {
    53.         Debug.Log ("Server called the Client RPC to register a client-specific handler");
    54.         ClientScene.RegisterSpawnHandler(assetId, SpawnEnemyHandler, UnSpawnEnemyHandler);
    55.     }
    57.     //This is only runs on remote clients
    58.     public GameObject SpawnEnemyHandler(Vector3 position, NetworkHash128 assetId)
    59.     {
    60.         Debug.Log ("We have entered the client-specific spawn handler");    
    61.         //Here we create a cube (but make it green instead) to illustrate separate functionality
    62.         //Normally we would want to recreate the same game object that the server used
    63.         GameObject otherCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
    64.         otherCube.transform.position = position;
    65.         otherCube.AddComponent<NetworkIdentity> ();
    66.         otherCube.GetComponent<MeshRenderer>().material.color =;
    67.         return otherCube;
    69.         //HELP - How can I access the server's game object from here?
    70.         //Can I do something with assetId here?
    71.     }
    72.    //This is only runs on remote clients
    73.     public void UnSpawnEnemyHandler(GameObject spawned)
    74.     {
    75.         Destroy (spawned);
    76.     }
    77. }
    I've looked for days and have found nothing but dead ends. I've seen this question asked all in multiple threads, but haven't found any legit answers yet. Please help!
    Last edited: Oct 27, 2016
  2. peterpi


    May 18, 2013

    What you could do is have the server send a spawn command for a prefab that serves as a common start point, and then call a series of ClientRpc functions to modify that instance into the desired object. That's how I'd do something like user-customizable avatars. Obviously the more open-ended the objects you want to spawn, the more work you'll have to do.
  3. ElGuapo


    Sep 27, 2016
    I hadn't thought of doing it this way, but it makes total sense. Thanks for the advice!

    I do have very complicated GameObjects, so this could get quite ugly. I'll try to see if I can serialize some of the more complicated parts to preserve my sanity.

    (I wish the documentation spelled this out. It talks about setting up the spawn handlers for spawning dynamic prefabs, but doesn't mention how you would actually go about doing that.)
  4. Oattjv


    Jun 28, 2017
    did you find out the solution?? I've got the same issue here..
  5. Joe-Censored


    Mar 26, 2013
    Did you try peterpi's idea? That is the way I would go with it. Spawn a known base prefab, and then send instructions to the clients using the various methods available to construct the custom object.
  6. ElGuapo


    Sep 27, 2016
    Unfortunately I did not. If I remember correctly, it became too cumbersome due to the many problems with the underlying assets I had chosen.

    I am by no means an expert in unity, so don't take my experience to mean that it is not possible. I generally remember being disappointed with how Unity (and many of it's assets) seems to be more aimed at a GUI/Load Time configuration and how difficult it was to specify Dynamic/Run Time configuration. I hope you will fare better than I. Good luck!