Search Unity

How to access server objects?

Discussion in 'Multiplayer' started by ghostravenstorm, Apr 21, 2017.

  1. ghostravenstorm

    ghostravenstorm

    Joined:
    Oct 18, 2015
    Posts:
    88
    I'm trying to figure out how to correctly implement a singleton pattern in a multiplayer game where the singleton and its game object only exist on the server, not any client.

    I ran into trouble when I set my singleton's network ID to server only which cause the singleton variable to be null on every client and its variables and methods could not be invoked. So its no longer server only which fixed my null reference issue, but now I have a singleton per client, so unless I apply [SyncVar] to all the singleton's properties, its not going to be unified across the board. I can set it up like this, but its redundant to allocate memory for a singleton on every client (and not truely a singleton) that has [SyncVar] on everything when there could be just one singleton server side that clients simply access.

    The problem I have is how the heck do I access server side only game objects?

    (I put down a random known tag just so I can post because the forum was giving me problems.)
     
  2. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    I'm not sure I understand your question, but for my UNET singleton what I do is
    -Register prefab in editor
    -Server: Instantiate Prefab
    -Server: Spawn prefab (It's important to instantiate & spawn the prefab as opposed to having it be part of a start scene or it will not work)
    -Server & Client: During Awake: singleton = this

    Then use SyncVar's on properties if that is the route you are going.

    But if you only want the Singleton on the Server then don't use a NetworkBehaviour at all. OnStartServer just instantiate your singleton if you only want it on the server.
     
  3. ghostravenstorm

    ghostravenstorm

    Joined:
    Oct 18, 2015
    Posts:
    88
    That makes sense, but if my singleton *only* exists on the server how would clients know of it if they wanted to invoke a method?
     
  4. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    If the clients are invoking it's methods then then it doesn't only exist on the server! :p
     
  5. ghostravenstorm

    ghostravenstorm

    Joined:
    Oct 18, 2015
    Posts:
    88
    So there is a singleton of game manager in memory for every client. I'm worried about synchronization though when storing variables. Make all its properties [SyncVar] I suppose.
     
  6. ghostravenstorm

    ghostravenstorm

    Joined:
    Oct 18, 2015
    Posts:
    88
    Wait, how would I spawn it without some other pre-existing manager script?
     
  7. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    You need 2 singletons objects
    1: NetworkManager (not a Networked GameObject). This starts the server and whatnot. I have this as part of my starting scene.
    2: CustomNetworkedSingleton (a NetworkBehaviour on a Networked GameObject that is instantiated & spawned during OnStartServer)

    Also keep in mind that UNET limits you to 32SyncVars/script so if you pile all SyncVars into a singleton it may exceed 32.
     
    Last edited: Apr 24, 2017
    Deleted User likes this.
  8. ghostravenstorm

    ghostravenstorm

    Joined:
    Oct 18, 2015
    Posts:
    88
    Yeah, I have Network Manager as part of my scene too, but how would I tell it to spawn Game Manager? I don't see a spot for custom spawning in the component expect for Player Prefab.
     
  9. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
  10. ghostravenstorm

    ghostravenstorm

    Joined:
    Oct 18, 2015
    Posts:
    88
    Should Game Manager be a Network Behaviour or Mono Beahviour?
     
  11. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    #1: Your GameManager singleton should be a MonoBehaviour. Not networked. Persistent and always there. No NetworkIdentity.
    #2: Your NetworkSingleton should be a NetworkBehaviour and spawned by the server when starting, and then destroyed when a client exits or the server shuts down. But could persist through scenes if you need.
     
  12. ghostravenstorm

    ghostravenstorm

    Joined:
    Oct 18, 2015
    Posts:
    88
    I see want you mean by my singleton not functioning properly. I'm trying to network spawn a timer object in my singleton script but I get this error on start.



    I have no idea what it means. My SyncVar roundTimer is not being set at all.

    Code (CSharp):
    1. public class GameManager : NetworkBehaviour{
    2.  
    3.    public static GameManager singleton;
    4.  
    5.    public GameObject countdownTimerPrefab;
    6.    public Text uiText;
    7.  
    8.    [SyncVar] public GameObject roundTimer;
    9.  
    10.    void Awake(){
    11.       if(singleton == null){
    12.          singleton = this;
    13.          DontDestroyOnLoad(gameObject);
    14.       }
    15.       else{
    16.          Destroy(gameObject);
    17.       }
    18.    }
    19.  
    20.    void Start(){
    21.       CmdInitializeTimer();
    22.    }
    23.  
    24.    [Command]
    25.    private void CmdInitializeTimer(){
    26.       this.roundTimer = GameObject.Instantiate(countdownTimerPrefab);
    27.       NetworkServer.Spawn(roundTimer);
    28.       this.roundTimer.GetComponent<CountdownTimer>().Initialize(3, 0, this.uiText, this.OnTimerExpired);
    29.       this.roundTimer.GetComponent<CountdownTimer>().StartTimer();
    30.    }
    31.  
    32.    public void OnTimerExpired(){
    33.  
    34.    }
    I'm still trying to figure out how to network spawn my singleton too. Right now its still in the scene.