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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Non Player Object - Spawning Object only on local Client

Discussion in 'Multiplayer' started by BahamutZeRo, Jun 18, 2016.

  1. BahamutZeRo

    BahamutZeRo

    Joined:
    Oct 19, 2015
    Posts:
    17
    [Latest Update - Refer to Comment below for a Simplified version]
    To the point, I have an Object called "Barrack". Every Local Player will be provided with a barrack in the game, so what this Barrack does is that it only just Spawn Unit. However I have an issue, I couldn't call these Spawned Unit(from the Barrack) to be shown in the Server from the Local Players that has the Barrack.

    Current Setting for the "Barrack" GameObject
    - It has NetworkIdentity with Local Player Authority.
    - This Barrack are being spawned by a script through an GameObject, which has its Network Identity(with ticked Server Only).

    This sample script below that does spawning "Barrack" for each player. Note this is not the Barrack spawning unit Script. This Code also work for Both Server and Clients.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Networking;
    4.  
    5. public class SampleScript : NetworkBehaviour
    6. {
    7.     public GameObject _Barrack;
    8.  
    9.     public override void OnStartServer()
    10.     {
    11.         if(isServer)
    12.         {
    13.             GameObject _Obj = (GameObject)Instantiate(_Barrack,transform.position,Quaternion.identity);
    14.  
    15.             NetworkServer.Spawn(_Obj);
    16.  
    17.             NetworkServer.Destroy(this.gameObject);
    18.         }
    19.     }
    Barrack script that does the spawning Unit it is only with the Code below:-
    Code (CSharp):
    1. void CreateBarrack()
    2. {
    3. GameObject _Obj = (GameObject)Instantiate(Unit_1,transform.position,Quaternion.identity);
    4. NetworkServer.Spawn(_Obj);
    5. }
    Sadly, Server can spawn Unit_1 to the Clients but not the other way round. I'm kinda confused with this already. So if anyone of you got where I made my mistake please do let me know~

    Thank you!
     
    Last edited: Jun 19, 2016
  2. BahamutZeRo

    BahamutZeRo

    Joined:
    Oct 19, 2015
    Posts:
    17
    Here's my latest update and I had simplified issued above.

    [Scenario]
    I have multiple of Barracks called Barrack1, Barrack2 and so on. The code below only makes it spawn on the last Barrack that has been built. I'm guessing the problem derives from the function - NetworkManager.RegisterHandler, since it does only registering a single spawnMessage?

    I could be wrong, So any of you know how do I spawn the soldier according to the position at their Barrack's? Need help badlyy

    This is my current code for the Barrack Spawning.
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Networking;
    3. using UnityEngine.Networking.NetworkSystem;
    4.  
    5. public class BarrackSpawn : NetworkBehaviour
    6. {
    7.     const short SpawnMessageType = 1000;
    8.  
    9.     void Start()
    10.     {
    11.         NetworkServer.RegisterHandler(SpawnMessageType, _NetSpawning);
    12.     }
    13.        
    14.     // This function can only be trigger from A Button(UI)
    15.     public void SummonSoldier() // When player press a Button on the Screen
    16.     {
    17.         NetworkManager.singleton.client.Send(SpawnMessageType, new EmptyMessage());
    18.     }
    19.  
    20.     void _NetSpawning(NetworkMessage NetMsg) // This does the spawning on the Client and Server
    21.     {
    22.         GameObject _Obj = (GameObject)Instantiate(Resources.Load("Soldier01")as GameObject,transform.position,Quaternion.identity); //This only refer to an Object.
    23.         NetworkServer.Spawn(_Obj);
    24.     }
    25. }
     
  3. Oshroth

    Oshroth

    Joined:
    Apr 28, 2014
    Posts:
    99
    You can only have one Handler registered per message type, so each Barrack overrides the previous handler. You need a singleton on the server that registers the handler and handles the message, and you need to pass a unique id(such as netid which can be used with FindLocalObject()) for the Barrack attempting to spawn a unit and use it to locate the correct Barrack on the server and call _NetSpawning() from there.

    Or, you can just use [Command]s on the Barracks to spawn units.
     
  4. BahamutZeRo

    BahamutZeRo

    Joined:
    Oct 19, 2015
    Posts:
    17
    @Oshroth . How do I do a Singleton on the server to registers handler? I know Command and ClientRpc do the job on Player Object, but can a Non-Player Object do it? How?

    Sorry I'm kinda still learning to UNET please forgive me if you are reading.
     
  5. Oshroth

    Oshroth

    Joined:
    Apr 28, 2014
    Posts:
    99
    There is a couple of pre-made Singleton templates you can find around for Unity.

    For [Command]s, you can assign client Authority to objects on clients to allow them to call [Command]s.
     
  6. BahamutZeRo

    BahamutZeRo

    Joined:
    Oct 19, 2015
    Posts:
    17
    @Oshroth . I found the Singleton templates and, I will now figure out to put them into piece of what you have taught me.
    Thank you for your solution, I will now work on it!
     
  7. BahamutZeRo

    BahamutZeRo

    Joined:
    Oct 19, 2015
    Posts:
    17
    Hi @Oshroth, I still didn't manage to do Singleton scripting for the following function Networkserver.RegisterHandler. If you don't mind, can you show me a Basic Sample code to use Singleton to register the Networkserver handlers for multiple of Barrack? My brain drained out doing this.