Search Unity

[Solved] NetworkServer.Spawn() Issues. Need help

Discussion in 'Multiplayer' started by Gunging, Dec 5, 2016.

  1. Gunging

    Gunging

    Joined:
    Sep 6, 2016
    Posts:
    139
    Well, I just started multiplayer code yesterday, and I have seen a few tutorials, but I cant manage to spawn a prefab for any other player but the host. I have my code sample here:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Networking;
    4.  
    5. public class SampleNetworkScript : NetworkBehaviour
    6. {
    7.     public GameObject spikyBall;        //Spiky Ball Prefab
    8.     private float spikyBallSpawnDelay;  //Spiky ball spawn delay (absolute)
    9.     public float spikyBallSpawnRate;    //Spiky ball spawn delay (relative)
    10.     private int bigOne = 0;             //Variable
    11.     public GameObject bigSpikyBallPrefab;//Big Spiky Ball Prefab
    12.     public bool End;                    //Variable
    13.     private float TimeLeft;             //Time Left
    14.     public GameObject CPUPrefab;        //NPC Character
    15.     private float CPUSpawnDelay;        //NPC Character spawn delay (absolute)
    16.     public float CPUSpawnRate;          //NPC Character spawn delay (relative)
    17.     public GameObject timer;            //A timer
    18.     private float endDelay;             //Variable
    19.  
    20.     void Awake()
    21.     {
    22.         End = false;                    //sets end to false (this is cause when time runs out, end becomes true and a lot of events trigger)
    23.         TimeLeft = 60;                  //No description needed
    24.     }
    25.  
    26.     void Start() { endDelay = Time.time + 63; } //Cause it gives 3 extra seconds for end animations and stuff
    27.  
    28.     void Update()
    29.     {
    30.         TimeLeft = timer.GetComponent<TimerScript>().TimeLeft; //Constantly updates as the time passes
    31.         if (Time.time > spikyBallSpawnDelay && bigOne < 3)  
    32.         {   //Will run CmdSpawnSmallSB (Spiky Ball) every spikyBallSpawnRate seconds
    33.             CmdSpawnSmallSB();
    34.         }
    35.         if (Time.time > spikyBallSpawnDelay && bigOne == 3)
    36.         {   //The same but with a Big Spiky Ball (This happens every 3 small ones)
    37.             CmdSpawnBigSB();
    38.         }
    39.         if (Time.time > CPUSpawnDelay)
    40.         {   //The same but with NPCs
    41.             CmdSpawnCPU();
    42.         }
    43.         if (TimeLeft <= 0 && End == false) { End = true; }
    44.     }
    45.     [Command]
    46.     void CmdSpawnSmallSB()
    47.     {
    48.         spikyBallSpawnDelay = Time.time + spikyBallSpawnRate; //Sets the absolute delay to be equal to the relative one plus current time
    49.         GameObject smallSB = (GameObject)Instantiate(spikyBall, new Vector3(Random.Range(-9, 9), Random.Range(-5, 5), 0), Quaternion.identity);
    50.         //Spawns the spiky ball in a random place in the playable scene space
    51.         bigOne++; //Ads one counter to spawn a big Spiky Ball
    52.  
    53.  
    54.         NetworkServer.Spawn(smallSB); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    55.     }
    56.     [Command]
    57.     void CmdSpawnBigSB()
    58.     {
    59.         //The same but with big spiky ball
    60.         spikyBallSpawnDelay = Time.time + spikyBallSpawnRate;
    61.         GameObject bigSB = (GameObject)Instantiate(bigSpikyBallPrefab, new Vector3(Random.Range(-9, 9), Random.Range(-5, 5), 0), Quaternion.identity);
    62.         bigOne = 0;
    63.  
    64.         NetworkServer.Spawn(bigSB); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    65.     }
    66.     [Command]
    67.     void CmdSpawnCPU()
    68.     {   //The same but with NPCs
    69.         CPUSpawnDelay = Time.time + CPUSpawnRate;
    70.         GameObject cPU = (GameObject)Instantiate(CPUPrefab, new Vector2(Random.Range(-8, 8), Random.Range(-4, 4)), Quaternion.identity);
    71.  
    72.  
    73.         NetworkServer.Spawn(cPU); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    74.     }
    75. }
    76.  

    I marked the NetworkServer.Spawn() with //!!!!!!!!!!!!!!!!!!! cuz those I think are the problem, as only the host gets to see the spawned prebafs the spiky balls and the NPCs.

    I dont know what I did wrong, please help xd

    ~Spiky balls are the only name I could come up with but are mor like a cactus seen from above, also they have no script, just a smooth come-out-from-the-ground animation.
     
  2. Jos-Yule

    Jos-Yule

    Joined:
    Sep 17, 2012
    Posts:
    286
    Is the SampleNetworkScript on the PlayerNetworkPrefab? ie. this is on the player game object? because you can only send Cmd/Rpc if you have authority.
     
  3. Gunging

    Gunging

    Joined:
    Sep 6, 2016
    Posts:
    139
    aouthority on what? Its not in the player game object, is in an out-of-screen gameobject which only function is to run this
     
  4. Jos-Yule

    Jos-Yule

    Joined:
    Sep 17, 2012
    Posts:
    286
    Does the GameObject the script is on have a NetworkIdentity component? Is it a scene object itself, ie. saved in the scene, or is it itself dynamically added to the scene?
     
  5. Gunging

    Gunging

    Joined:
    Sep 6, 2016
    Posts:
    139
    Saved in the scene, is a 2D sprite (cause is a 2D game), it contains:
    Sprite Renderer,
    Network Identity (Marked as Local player authority cause when I marked it as server it dissapeared and did nothing)
    SampleNetworkScript (I couldnt decide another name when first created it)
    Material (Sprites-Default)
     
    Last edited: Dec 7, 2016
  6. Jos-Yule

    Jos-Yule

    Joined:
    Sep 17, 2012
    Posts:
    286
    I'd uncheck the Local Player Authority bool, but also do not check the server only one.
     
  7. Gunging

    Gunging

    Joined:
    Sep 6, 2016
    Posts:
    139
    lol Id never imagine you could check none and it would still work, sorry for not replying, Ive been having a lot of work lately.

    The spiky balls still only appear for the host :c, is there any difference between networking 3D and 2D? cause in a 3D tutorial I saw, these commans worked fine to spawn a prefab in all the clients and host, and well, my game is 2D
     
    Last edited: Dec 8, 2016
  8. Gunging

    Gunging

    Joined:
    Sep 6, 2016
    Posts:
    139
  9. Gunging

    Gunging

    Joined:
    Sep 6, 2016
    Posts:
    139
    Oh well I think I got the problem now.... the spiky ball isnt in the network manager's registered spawnable prefabs list xd

    I feel so stupid
     
  10. Gunging

    Gunging

    Joined:
    Sep 6, 2016
    Posts:
    139
    Well, now it works, after like 5 hours of changing stuff in all the prefabs and fixing singleplayer, now it works :D, thank you a lot Jos-Yeule
     
  11. Jos-Yule

    Jos-Yule

    Joined:
    Sep 17, 2012
    Posts:
    286
  12. magno-4329062

    magno-4329062

    Joined:
    Jun 4, 2017
    Posts:
    1
    how did you do it? :'u
     
  13. Gunging

    Gunging

    Joined:
    Sep 6, 2016
    Posts:
    139
    This was a long time ago, but I can tell you how I do it now:

    "Spawner" means an object that is only there to make stuff appear, like a minigame in which you just need an empty gameObject with a script making stuff appear from time to time.

    First of all, you need to have an object to spawn, you may skip any number of steps 1-4 if you already have done them:
    1) Make the object you want to generate, lets call it "Shiny Shoe". (This includes scripts, children, and all that stuff)
    2) Put the Network Identity component in the Shiny Shoe.
    3) Drag the Shiny Shoe from the Hierarchy Tab to a folder in the Project Tab. This will create its Prefab.
    4) Include the Shiny Shoe Prefab in the "List of Spawnable Prefabs" of your Network Manager.

    Now to create the actual spawner:
    5) You create an empty gameObject, put a Network Identity in it and select the "Server Only" bool.
    6) Put your spawner code in it, this is how you spawn something:
    Code (CSharp):
    1.     public GameObject shinyShoePrefab; //You assign the Shiny Shoe Prefab through the inspector.
    2.     Vector3 shinyShoeSpawnPosition; //Explained by itself, it is completely up to you how to set this.
    3.     Quaternion shinyShoeSpawnRotation; //Explained by itself, it is completely up to you how to set this.
    4.  
    5.     private void Update() {
    6.         //Checks if the conditions to spawn the shiny shoe are met.
    7.         if (conditionsToSpawnShinyShoeMet) { SpawnShinyShoe(); } //If they are met, it spawns the shiny shoe
    8.     }
    9.  
    10.     [Command] void SpawnShinyShoe() { //Note that it is a command, very important.
    11.        GameObject newShinyShoe = (GameObject)Instantiate(shinyShoePrefab, shinyShoeSpawnPosition, shinyShoeSpawnRotation);
    12.         //The Instantiate() command should work with any of its variants or overloads.
    13.         newShinyShoe.GetComponent<ShinyShoeScript>().sampleFloatSyncVar = 10; //This value is set to 10
    14.         newShinyShoe.GetComponent<ShinyShoeScript>().sampleFloatWithNoSyncVarAttribute = 15; //This is set to 15
    15.         NetworkServer.Spawn(newShinyShoe); //AFTER the values are set, you send this command and the Shiny Shoe will appear across the network.
    16.     }
    7) You are ready! Add your scene to build and compile (or just go into play mode). Make sure you have a Network Server active.

    Note that the class "ShinyShoeScript" has two values:
    Code (CSharp):
    1. [SyncVar] public float sampleFloatSyncVar;
    2. public float sampleFloatWithNoSyncVarAttribute;
    Well, I assume you are starting to do multiplayer, so I just thought it was worth mentioning that even though the spawning code sets both values to a number, only the one with the [SyncVar] attribute will be updated for the clients. In other words, the host will see both values as the number they were given in the void SpawnShinyShoe(), but the clients will only update to 10 the float sampleFloatSyncVar and continue to see the float sampleFloatWithNoSyncVarAttribute as 0. Same with all values that you set this way.
     
unityunity