Search Unity

Third Party Mirror - Object reference between two Network Spawned objects

Discussion in 'Multiplayer' started by brainwipe, Oct 26, 2020.

  1. brainwipe

    brainwipe

    Joined:
    Aug 21, 2017
    Posts:
    78
    I want to Network Spawn two objects which need an object reference between them. How do I do this? This is what I would like to achieve:

    Code (CSharp):
    1.  
    2.  
    3. public class Quest : NetworkBehaviour
    4. {
    5.     [SyncVar]
    6.     public QuestTracker Tracker;
    7. }
    8.  
    9. public class Factory : NetworkBehaviour {
    10.  
    11.     [Server]
    12.     public void QuestFactory()
    13.     {
    14.          var quest = Instantiate(questPrefab, Vector.zero, Quaternion.identity);
    15.          NetworkServer.Spawn(quest);
    16.  
    17.           var questTracker = Instantiate(questTrackerPrefab, Vector.zero, Quaternion.identity);
    18.           NetworkServer.Spawn(questTracker);
    19.  
    20.           quest.Tracker = questTracker;
    21.     }        
    22. }
    23.  
    At this point questTracker doesn't have an id (it's not been spawned).

    So I moved the instantiation of quest tracker into Awake() of Quest, so that it is hard dependency. However, I still can't get the object reference.

    Code (CSharp):
    1.  
    2.  
    3. public class Quest : NetworkBehaviour
    4. {
    5.     [SyncVar]
    6.     public QuestTracker Tracker;
    7.  
    8.     protected virtual void Awake()
    9.     {
    10.           MyTrackerGameObject = (GameObject)Instantiate(questTrackerPrefab, Vector.zero, Quaternion.identity);
    11.           NetworkServer.Spawn(MyTubeGameObject);
    12.  
    13.           Tracker = MyTubeGameObject.GetComponent<QuestTracker>();
    14.      }
    15.  
    But that didn't work either.

    This feels like a standard practise but I can't find anything on the docs or Googling.

    NB: Names of methods/variables simplified, some code removed to get to the nub of the issue; I hope I haven't introduced unintended errors by doing so.

    Many thanks in advance.
     
    qball13z likes this.
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    SyncVar has a limited list of supported types, basically basic types and some Unity types. So you can't use it for syncing a QuestTracker type. What I do is put some kind of identifier on the object, and when they spawn on the client have one object find the other based on the identifier. The identifier could be a tag, it could be a value on a script attached to the object, etc.
     
    vaderporpoise, qball13z and brainwipe like this.
  3. brainwipe

    brainwipe

    Joined:
    Aug 21, 2017
    Posts:
    78
    Thank you @Joe-Censored for your reply. I've experimented a little more and I think that's the best way to go. I've read many of your comments across the site and may I take the opportunity to thank you for your tireless work here. You're very much appreciated.

    Another option, for those reading, is not to reference them on the client at all. In my naive mind, I am trying to make the server and the client to be as close as possible in terms of object references and state but I think that it's not necessary.

    In a server-controlled world, the client doesn't need to have a full simulation of the game world. It doesn't need to run the game rule logic. It needs enough information to allow the client-authority objects (such as the player) to perform physics and simple interactions but otherwise the biggest job of the client is to command the server to update state on its behalf.

    I think that's what I'm doing wrong here.

    The two objects need to have that reference on the server but they don't on the client. The clients need to have those objects but the logic should be run on the server. Either I split out the client/server logic or I accept that the reference between Tracker and its Quest will be null on the client.

    Sorry if this is obvious to all, I hope it will come in useful to some!
     
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Yeah, the most common reason I set up these references also on the client is for accessing synced data for display to the player. If it is for server logic, then as you pointed out the reference is not needed. Something I found helpful, if I'm leaving a reference null on the client I add a comment where I declare the variable saying so. Helpful reminder 6 months later whether that reference is actually available on the client or not.
     
    qball13z and brainwipe like this.
  5. vaderporpoise

    vaderporpoise

    Joined:
    May 28, 2020
    Posts:
    2
    are you rob Lang, really cool youtube channel, love it
     
  6. brainwipe

    brainwipe

    Joined:
    Aug 21, 2017
    Posts:
    78
    Yes, I am thank you! Brainwipe is my alter ego I've used since 1996. I'm glad using my face everywhere is helpful.
     
    vaderporpoise likes this.