Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Command Attribute issue

Discussion in 'Multiplayer' started by Bigbeef, Mar 14, 2017.

  1. Bigbeef

    Bigbeef

    Joined:
    Apr 6, 2013
    Posts:
    31
    So I am trying to set up a system where I can remotely control my game from either the host machine, or a connected client on another machine (basically allowing 2 different people on 2 different machines to control the player's combat units in my game) and right now my code is working when I control the game from the host, but it's not working if I try to control the game from the client.

    When I tell a unit in the game to move on the host, the unit moves to the correct tile, and on the client you can see the action is executed correctly there as well. But if I try to tell a unit to move on the client, I get the warning "Trying to send command to object without authority".

    To accomplish what I have so far, I have a script that controls unit movement, and on mouseClick, it executes a [Command] function, that in turn calls a [ClientRpc] function. The hope of doing this was that a player would click on a tile, and that would send the command to the server, where the server could broadcast the ClientRpc function basically making all the clients execute the same function at the same time.

    But like I said, it only works correctly on the Host and doesn't work when I'm playing on a client connected to the host.

    Any help on this would be appreciated.

    My current code looks something like this

    Code (CSharp):
    1. //PlayerUnitController gameobject has a network identity set to //Local Authority
    2. public class PlayerUnitController : NetworkBehaviour
    3. {
    4. void Update()
    5.     {
    6.  
    7.         if (Input.GetMouseButtonDown(0))
    8.         {
    9.             CastRay();
    10.         }
    11.  
    12.     }
    13.  
    14. void CastRay()
    15.     {
    16.         Ray ray = topDownCamera.ScreenPointToRay(Input.mousePosition);
    17.         RaycastHit hit;
    18.         if (Physics.Raycast(ray, out hit, 100))
    19.         {
    20.             if (hit.collider.gameObject.tag == "tile")
    21.             {
    22.                 CmdMsgRayHitToServer(hit.collider.gameObject);
    23.             }
    24.         }
    25.  
    26.     }
    27.  
    28. [Command]
    29.     void CmdMsgRayHitToServer(GameObject _hit)
    30.     {
    31.         RpcSyncMoveWithAllClients(_hit);
    32.  
    33.     }
    34.  
    35.     [ClientRpc]
    36.     void RpcSyncMoveWithAllClients(GameObject hitGameObject)
    37.     {
    38. //perform unit move code.....
    39.     }
    40.  
    41. }
     
  2. DavidGrof

    DavidGrof

    Joined:
    Sep 13, 2016
    Posts:
    24

    You can net have GameObjects as the parameter.
    Only use primitives, since GameObject can not be serialized.
     
  3. Bigbeef

    Bigbeef

    Joined:
    Apr 6, 2013
    Posts:
    31
    Thank you for trying to help, but your comment isn't correct. According to the documentation:

    Arguments to Remote Actions
    The arguments passed to commands and ClientRpc calls are serialized and sent over the network. These arguments can be:

    • basic types (byte, int, float, string, UInt64, etc)
    • arrays of basic types
    • structs containing allowable types
    • built-in unity math types (Vector3, Quaternion, etc)
    • NetworkIdentity
    • NetworkInstanceId
    • NetworkHash128
    • GameObject with a NetworkIdentity component attached

      The tile gameobject that I'm passing through the command / Rpc functions is a gameobject with Network Identity component attached, so that's not the problem.

      The code works perfectly on the host and I can see the other client running the game stay in sync with unit moves made on the host. On the Host computer, I tell a unit to move from tile1 to tile12 and on the host the unit moves, and on the client machine I see the unit move correctly.

      So clearly the code is working, it's just that I'm only apparently allowed to control the units from the host machine, and the 2nd player connected as just a client "doesn't have authority".

      So is there something I need to do to dynamically transfer authority depending on who is performing the actions?
     
  4. DavidGrof

    DavidGrof

    Joined:
    Sep 13, 2016
    Posts:
    24
    Well it does not work for me with gameobject with networkid. only with primitives.