Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Spawn prefab dynamically

Discussion in 'Multiplayer' started by kigm, Jun 21, 2016.

  1. kigm

    kigm

    Joined:
    May 13, 2016
    Posts:
    29
    Hello, I am building a game where server starts and nothing is showed.
    Then when the first client connects to server, client tell to server which prefab load with authority for this first client, he can move the 3Dmodel.
    When the second client connects to server he should load the prefab that first client told to server (just spawn the model) and see how first client moves his "player" = 3Dmodel.

    The problem is when second client connect to server he doesn't spawn the prefab because he doesn't know which prefab is and he obtain "Failed to spawn server object assetid=.....".
    Obviously client hasn't registered the prefab. ClientScene.RegisterPrefab(gameobject) should solve the problem, but when a client connect to the server, server tells to new client "spawn this gameobject" and client doesn't know which gameobject is because he isn't registered yet, this is main problem here.

    For managing the problem I created 2 synced variables that represent (bool) if a model is loaded and (string) model name. So clients can register before server tells them "spawn this".
    I am using RegisterSpawnHandler instead of RegisterPrefab on clients because docs say this is the best way for manage this situation, but when second client connect to server he isn't syncing well the variables above mentioned.

    This is my code:

    Code (CSharp):
    1. public class networkClient : NetworkBehaviour {
    2.  
    3.     [SyncVar(hook = "OnModelLoadedChange")]
    4.     public bool modelLoaded;
    5.        
    6.     [SyncVar]
    7.     public string modelName;
    8.  
    9.     GameObject localModel;
    10.  
    11.     void Start () {
    12.  
    13.         if (isClient){
    14.             if (modelLoaded) { //model loaded?
    15.                 print("model loaded previously, model " + modelName+" will be loaded");
    16.            
    17.                 loadModel (modelName);
    18.             }
    19.             else {
    20.                 print ("No model loaded, loading...");
    21.                 print (modelLoaded);
    22.                 print (modelName);
    23.                 loadModel ("Tower");
    24.             }
    25.         }
    26.     }
    27.  
    28.     void loadModel(string modelName){
    29.         localModel = Resources.Load("Models/"+modelName) as GameObject;
    30.         //GameObject iGo = Instantiate (go) as GameObject;
    31.         ClientScene.RegisterSpawnHandler(localModel.GetComponent<NetworkIdentity>().assetId, SpawnHandler, UnSpawnHandler);
    32.         //ClientScene.RegisterPrefab (localModel);
    33.  
    34.         CmdLoadModel (modelName);
    35.     }
    36.  
    37.     private GameObject SpawnHandler(Vector3 position, NetworkHash128 assetID)
    38.     {
    39.         Debug.Log("Called Spawn Handler");
    40.         GameObject go = Instantiate (localModel) as GameObject;
    41.         return go;
    42.     }
    43.  
    44.     private void UnSpawnHandler(GameObject localModel)
    45.     {
    46.         Debug.Log("Called UnSpawn Handler");
    47.         DestroyImmediate (localModel);
    48.     }
    49.  
    50.     [Command]
    51.     void CmdLoadModel(string modelName){
    52.        
    53.         print ("Loading 3D model: "+modelName);
    54.  
    55.         this.modelName = modelName;
    56.  
    57.         //GameObject go = Resources.Load("Models/"+modelName) as GameObject;
    58.         //GameObject iGo = Instantiate (go) as GameObject;
    59.         localModel = Resources.Load("Models/"+modelName) as GameObject;
    60.  
    61.         if (!modelLoaded) {
    62.             print ("spawning with authority");
    63.             //networkManager.GetComponent<NetworkManager> ().spawnPrefabs.Add (go);
    64.            
    65.             NetworkServer.SpawnWithClientAuthority (localModel, connectionToClient);
    66.         } else {
    67.             print ("spawning without authority");
    68.             NetworkServer.Spawn (localModel);
    69.         }
    70.  
    71.         modelLoaded = true;
    72.     }
    73.    
    74.     private void OnModelLoadedChange(bool state){
    75.         print ("modelLoaded changed on client");
    76.         modelLoaded = state;
    77.     }
    78. }
    The documentation is very poor, and it doesn't explain so well many things about networking, this is for I am writing this.

    Can anybody help me?

    Thanks.
     
  2. kigm

    kigm

    Joined:
    May 13, 2016
    Posts:
    29
    up! anybody has to know something about this
     
  3. cernys

    cernys

    Joined:
    Jun 1, 2016
    Posts:
    18
    Hello, Did you find a solution ? I have a similar problem..
    With this reply it up your post anyway..
     
  4. kigm

    kigm

    Joined:
    May 13, 2016
    Posts:
    29
    Yes, I found a solution using synced vars like I mentioned above and using scenes.
    Now I have two scenes, one where I use www class and I make a request to the server obtaining the name of the model to load. Afterwards I register with ClientScene.RegisterPrefab(model) and the next is load the scene two where connect to UNET server and in this moment I have in my new scene the model registered, therefore the problem is solved.