Search Unity

Third Party Mirror: How do I get Server object references

Discussion in 'Multiplayer' started by MentalGames, Oct 9, 2020.

  1. MentalGames

    MentalGames

    Joined:
    May 2, 2016
    Posts:
    40
    Hi partypeople,

    I really hoped I wouldn't have to ask questions like this so early in development, but this one makes my head spin. How can I get a reference to an object spawned on the Server with Mirror?

    It seems like in UNET, there was the possibility to get it via netId and a list of objects, that doesn't exist in Mirror:

    NetworkServer.objects[netId].gameObject

    In my case, I have a spawned arena and because there can only be one, I would love to have a static instance with all the information that other objects and players require (like spawnpoints). And since Commands and Rpc calls don't return values, I don't really see an easy solution to this.

    Is this the wrong workflow? Am I missing something?

    Any help would be highly appreciated and I also take two cents.

    Cheers!
     
    Last edited: Oct 9, 2020
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    When you instantiate the object it returns the reference. You can use that same returned reference on the server after you call Spawn on it. Assign it to your static instance, etc.
     
    MentalGames likes this.
  3. MentalGames

    MentalGames

    Joined:
    May 2, 2016
    Posts:
    40
    Thanks for the fast reply! But what about objects that were created on the server? Or is there no reason to run the spawn code on the server? I'm still new to this and don't quite understand what code should run on the server and what should run on the client and be synchronized. I just read that because it could be potentially abused by cheaters, the more code goes to the server-side the better, but please correct me if I'm wrong :)
     
    Last edited: Dec 11, 2020
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    I'm not sure I understand. When you "create" an object on the server, normally the process is on the server you Instantiate a prefab, and then spawn that instantiated prefab. A call to Instantiate, which returns a reference to the instantiated object, which you then pass to Spawn. The object then appears on all clients. The reference originally returned from the Instantiate call on the server is the same reference to the object after it is spawned.

    On the clients if you want a reference to the same object, you can capture it in a Start method on the object itself, or find the object after it should already have appeared.

    And yeah, generally you can reduce some forms of cheating if you trust the client as little as possible with as much of your logic on the server as you can.
     
    Ishidres and MentalGames like this.
  5. MentalGames

    MentalGames

    Joined:
    May 2, 2016
    Posts:
    40
    I think I get it now. I didn't understand that "the reference originally returned from the Instantiate call on the server is the same reference to the object after it is spawned."

    I did as you said and it works.

    Thanks again!
     
    Joe-Censored likes this.
  6. MentalGames

    MentalGames

    Joined:
    May 2, 2016
    Posts:
    40
  7. Kurbot

    Kurbot

    Joined:
    Apr 30, 2014
    Posts:
    2
    I know this is an old post, but i wanted to shed some light on this topic as most newcomers still get lost when it comes to identifying the client and server objects associated with COMMAND's and RPC's.

    I wanted to share what i do in case it helps others still:

    I made a NetworkObject class that i use as a baseclass for all my other networkbehavior scripts, such as Item,Interactable Scenery, Chests, Npc, Player, etc

    Code (CSharp):
    1. using Mirror;
    2. using System.Collections.Generic;
    3.  
    4. public class NetworkObject : NetworkBehaviour {
    5.  
    6.         // Dictionary to store spawned gameobjects by netId |  Usage: spawnedNetworkObjects[netId]
    7.         public static Dictionary<uint,NetworkObject> spawnedNetworkObjects = new Dictionary<uint, NetworkObject>();
    8.  
    9.         // Add this object to the dictionary
    10.         public virtual void Start()
    11.         {
    12.             spawnedNetworkObjects.Add(netId, this);
    13.         }
    14.  
    15.         // Remove this object from the dictionary
    16.         public virtual void OnDestroy()
    17.         {
    18.             spawnedNetworkObjects.Remove(netId);
    19.         }
    20. }
    Example of it in use from a Player
    Code (CSharp):
    1. public class Player : NetworkObject
    2. {
    3.         public override void Start()
    4.         {
    5.               base.Start();
    6.               if (isServer)
    7.                    Debug.Log($"Find Myself On server: {spawnedNetworkObjects[netId].name}");
    8.  
    9.               if (isLocalPlayer)
    10.               {
    11.                    Debug.Log($"Find Myself On Local Client: {spawnedNetworkObjects[netId].name}");
    12.                    Debug.Log($"Same as this: {name}");
    13.               }
    14.         }
    15. }
    This can also be used from other classes or commands as well using the full static method

    Code (CSharp):
    1. NetworkObject.spawnedNetworkObjects[netId];
    And you can use it to find Components attached to the object just like any other GameObject.

    Code (CSharp):
    1. NetworkObject.spawnedNetworkObjects[netId].GetComponent<T>();
    2. NetworkObject.spawnedNetworkObjects[netId].transform;
    3. NetworkObject.spawnedNetworkObjects[netId].gameObject;
    4. // Etc
    I tend to use this method when i need a client to send a command to the server, with a netID and any additional parameters of the object im interacting with, then i can just look it up with NetworkObject.spawnedNetworkObjects[netId].

    Again i know this post was old, but i wanted to elaborate more as this was one of the first results on google when it comes to this topic.

    If you want more information let me know.
     
    Xian75 and jessekcooley like this.