Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  4. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Unity Multiplayer AssignClientAuthority

Discussion in 'Connected Games' started by Skerbey, Oct 28, 2015.

  1. Skerbey

    Skerbey

    Joined:
    Oct 15, 2015
    Posts:
    11
    Hello,

    I was wondering if anyone knew the correct way to use AssignClientAuthority. What I am trying to do is have players pick up object by clicking on them. This is my process:
    1. Players click on object
    2. A command is called with the object and the players NetworkIdentities passed as parameters
    3. The command calls AssignClientAuthority on the object (which has LocalPlayerAuthority checked) and assigns it to the connectionToClient of the player
    4. The player then becomes the parent of the object and can move the object
    5. The local player sends positional updates to the server of the object to be synced across all clients
    At one point this seemed to work, however now The issue I am getting is that authority isn't actually being assigned and when I try to access the ClientAuthorityOwner of the object later I get a null reference because authority was not assigned even though hasAuthority seems to have been checked on the object on the local client.

    Here is an example of my code (assume we already have references to the object and the player):

    Code (CSharp):
    1.  
    2. void Update () {
    3.     if (isLocalPlayer){
    4.         if(Input.GetButtonDown("Fire1") {
    5.             CmdSetAuthority(object.GetComponent<NetworkIdentity>(), player.GetComponent<NetworkIdentity>());
    6.         }
    7.     }
    8. }
    9.  
    10. [Command]
    11. void CmdSetAuthority(NetworkIdentity grabID, NetworkIdentity playerID) {
    12.     grabID.AssignClientAuthority(playerID.connectionToClient);
    13. }
    From what I've seen this is the correct way to implement this and it did work at some point so at this point I'm not sure if I have misunderstood how UNet handles authority or I have stumbled upon a bug. Does anyone have any idea?


    Cheers,

    Skerbey
     
  2. Skerbey

    Skerbey

    Joined:
    Oct 15, 2015
    Posts:
    11
    Has anyone managed to assign client authority correctly?
     
  3. Mike_Sp

    Mike_Sp

    Joined:
    Nov 1, 2015
    Posts:
    1
    yes! I just got this working for myself!

    Instead of playerID.connectionToClient, it's just connectionToClient
    So your line 12 would be:


    Code (CSharp):
    1. grabID.AssignClientAuthority(connectionToClient);
    2.  
    Thanks to you I got this working on my project, I was having trouble with the part you have as "grabID".
     
    pKallv likes this.
  4. Skerbey

    Skerbey

    Joined:
    Oct 15, 2015
    Posts:
    11
    This hasn't solved it for me. The both lines of code seem to be identical for me as the script is on the player so connectionToClient gets the connection form the players NetworkIdentity anyway.

    The issue I have been having is that when AssignClientAuthority is called the hasAuthority flag on the local object is set to true, however the clientAuthorityOwner field on the grabbed objects NetworkIdentity is not set. This becomes an issue for me when scripts on my grabbed object try to refer to their owner.

    I have isolated the code for this and sent it as a bug report as I am certain that is not the intended functionality. Awaiting a response from Unity...
     
  5. pKallv

    pKallv

    Joined:
    Mar 2, 2014
    Posts:
    740
    A BIG thank you :)
     
  6. LHAppri

    LHAppri

    Joined:
    Aug 18, 2017
    Posts:
    7
    This was not correct for me. If you just use connectionToClient, you are using the connection for the Player running this function. If you are using a [Command] function you are running it on the Server's Player, and so you would be assigning that connection, not the connection from whichever client had called the function. I used playerID.connectionToClient as in the original post and that worked, so I'm guessing the original problem may have been a bug that is now fixed. [Note I'm running 2018.1.1f1]
     
  7. hottabych

    hottabych

    Joined:
    Apr 18, 2015
    Posts:
    69
    Catch the working script. Put this on your Player. Parameter is an identity you want to set authority.

    Code (CSharp):
    1.     [Command]
    2.     void CmdSetAuthority(NetworkIdentity identity)
    3.     {
    4.         var currentOwner = identity.clientAuthorityOwner;
    5.  
    6.         if (currentOwner == connectionToClient)
    7.         {
    8.             return;
    9.         }
    10.         else
    11.         {
    12.             if (currentOwner != null)
    13.             {
    14.                 identity.RemoveClientAuthority(currentOwner);
    15.             }
    16.             identity.AssignClientAuthority(connectionToClient);
    17.         }
    18.     }

    hasAuthority for non-player object is the same to isLocalPlayer for Player object.
    clientAuthorityOwner is null, if an object is under Server authority. So if you check hasAuthority on your Host, it should be true.