Search Unity

Trouble getting interactive, non-player objects working

Discussion in 'Multiplayer' started by mr_pablo, May 10, 2017.

  1. mr_pablo

    mr_pablo

    Joined:
    Jun 26, 2014
    Posts:
    12
    I am trying to get interactive, non-player objects (spawned by the server) to work so that two players can change its state (in this case, turn a light on and off) and have the state synced correctly across clients.

    For testing, I am running the game via Unity and having the PC as the host (server and client) and my phone as a second client.

    I have a spawner object, that has a Network Identity component, with the Server only box ticked.

    It has the following script attached:

    Code (CSharp):
    1.  
    2. public class TargetSpawner : NetworkBehaviour
    3. {
    4.     public GameObject targetPrefab;
    5.  
    6.     public override void OnStartServer()
    7.     {
    8.         GameObject targetObj = (GameObject) Instantiate(targetPrefab);
    9.         NetworkServer.Spawn(targetObj);
    10.     }
    11. }
    12.  
    This seems to work fine, both clients (PC and Phone) can see the object (a cube, with a light as a child)

    Then, I have the following script on the cube prefab:

    Code (CSharp):
    1.  
    2. public class GazeInteraction : NetworkBehaviour
    3. {
    4.     [SyncVar]
    5.     public bool isLightOn = false;
    6.  
    7.     void Update()
    8.     {
    9.         if (isLightOn)
    10.         {
    11.             gameObject.GetComponentInChildren<Light>().enabled = true;
    12.         }
    13.         else
    14.         {
    15.             gameObject.GetComponentInChildren<Light>().enabled = false;
    16.         }
    17.     }
    18.  
    19.     public void TurnOnLight()
    20.     {
    21.         CmdEnableLight();
    22.     }
    23.  
    24.     [Command]
    25.     void CmdEnableLight()
    26.     {
    27.         if (!isLightOn)
    28.         {
    29.             isLightOn = true;
    30.         }
    31.         else
    32.         {
    33.             isLightOn = false;
    34.         }
    35.     }
    36. }
    37.  
    TurnOnLight() is activated via an input event.

    What happens when I run this, is that the host (PC acting as server and client) can turn the light on and off, and the other client (a phone) can see it happen, but they cannot interact with the cube/light.

    I've tried looking for the information I need, but anything I read about non-player objects tends to be super basic and I simply cannot find any good information on how to make this kind of setup work.

    Can anyone help me out or point me in a good direction to figuring out the issue?

    Cheers!

    EDIT - just to give more info, the cube prefab that gets spawned currently has its network identity set to local player. I have no idea if this is correct or not.
     
    Last edited: May 10, 2017
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    You can only send commands if the client has authority over the object or if it is the client's player object, so if you're calling TurnOnLight() on any client other than the one machine with authority, it won't work. The cube prefab will default to the server having authority when it is spawned by the server.

    You could consider on your player object creating an interact command, and when called the server version of the player object then calls TurnOnLight() on the cube.
     
  3. mr_pablo

    mr_pablo

    Joined:
    Jun 26, 2014
    Posts:
    12
    What is the difference between having the script on the cube or the player? Ideally, I want to keep it on the cube, as it's something to do with the cube directly.

    I am in a state now where I can see warnings about the objects authority, so now the question is extended to (and the original still applies as it hasn't been answered fully) "how do I assign authority to whichever user is trying to interact with it?"