Search Unity

NullReferenceException when passing local GameObjects through Command and ClientRpc - SOLVED

Discussion in 'Multiplayer' started by nensl, Dec 15, 2017.

  1. nensl

    nensl

    Joined:
    May 30, 2016
    Posts:
    6
    I'm working on a little Quiz Multiplayer Game and am almost done but I can't get the GameObjects holding the answers from each player synchronized.

    My understanding so far:
    When trying to synchronize something on all clients while using local Variables/GameObjects I have to pass them through a [Command] before calling a [ClientRpc] Method. Sadly I'm always getting a NullReferenceException.

    My Code look something like this:

    Code (CSharp):
    1. public IEnumarator CheckAnswer(int questionID, string answer) {
    2.         WWW data = ... ;
    3.         yield return data; // getting data from a website
    4.  
    5.         GameObject answerCanvas = ... ;
    6.         GameObject answerFieldText = ... ;
    7.         GameObject answerFieldPoints = ... ;
    8.         int points = int.Parse(data.text);
    9.  
    10.         CmdSetAnswer(answerCanvas, answerFieldText, answerFieldPoints, points, answer);
    11. }
    12.  
    13.     [Command]
    14.     public void CmdSetAnswer(GameObject answerCanvas, GameObject answerFieldText, GameObject answerFieldPoints, int points, string answer)
    15.     {
    16.         RpcSetAnswer(answerCanvas, answerFieldText, answerFieldPoints, points, answer);
    17.     }
    18.  
    19.     [ClientRpc]
    20.     public void RpcSetAnswer(GameObject answerCanvas, GameObject answerFieldText, GameObject answerFieldPoints, int points, string answer)
    21.     {
    22.         answerFieldText.GetComponent<Text>().text = answer; //NullReferenceException
    23.         answerFieldPoints.GetComponent<Text>().text = points.ToString(); //NullReferenceException
    24.         answerCanvas.SetActive(true); //NullReferenceException
    25.     }
    Does anybody have an idea how to deal with this issue? Is my concept even right for changing GameObjects on every client?

    Appreciating any help :)
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    You can't pass "local" GameObjects through a remote action.

    https://docs.unity3d.com/Manual/UNetActions.html

    So only networked GameObjects, not local GameObjects can be passed as arguments to a command or clientrpc.
     
    nensl likes this.
  3. Driiades

    Driiades

    Joined:
    Oct 27, 2015
    Posts:
    151
    You have to understand that you can pass only information in byte/int/float/String.

    You can't pass a pointer reference to an object (in fact you could if every computer has the same reference pointing on the same gameobjects... it's not the fact). When you call a command with a gameObject you pass in fact the netId of the gameObject. That's why it need to be networked with for example a networkIdentity.

    For this to be right, you need also that this networkd Gameobject is present on server also (don't destroy it on server for example).
     
    nensl likes this.
  4. hellaeon

    hellaeon

    Joined:
    Jul 20, 2010
    Posts:
    90
    Hey Jawah, How did you end up solving this. UNET is doing my head in.
     
  5. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    LOL, not helpful to put "SOLVED" in your thread title with no mention of how the issue was solved
     
  6. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    As it regards solutions, in many use cases, the goal is to fetch the same object on client as on server, and vice versa.

    2 basic solution variants are:

    a) Game objects which need to be synced are networked objects and each has a NetworkBehavior. In this case, they automatically have a NetworkInstanceId and you can pass this ID to fetch them on either server or client. I would recommend this if you have a smaller number of objects.

    b) A custom system is implemented that generates and assigns ID's for objects and which provides a function to fetch an object with a given ID. Of course, you need to make sure that objects have the same IDs on both server and client. For example, if you have preplaced objects, you could simply assign IDs upfront in the editor. In contrast, if you need to deal with runtime generated objects, you could generate unique IDs on the server and send them along with an object spawn message so that the client knows the ID and has it assigned with the very same object. Eventually, you just need to sync your custom IDs across the network. I would recommend such a solution in case that you have quite a lot of objects and do not want to make each of them a networked Object with a NetworkBehavior.
     
    Last edited: Jan 9, 2018