Search Unity

Local player authority

Discussion in 'Multiplayer' started by iShadowfax, Dec 9, 2015.

  1. iShadowfax

    iShadowfax

    Joined:
    Mar 18, 2015
    Posts:
    38
    lease explain how can I use Local Player Authority on a player object in case I do not use NetworkTransform.

    For example I have:

    Code (CSharp):
    1. publicclassPlayerController:NetworkBehaviour{
    2. voidUpdate(){
    3. if(hasAuthority){
    4. //how can i manage server player object from here?
    5. }
    6. }
    7. }
     
  2. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    Need more information. For starters are you using (because you should be) NetworkIdentity?
     
  3. iShadowfax

    iShadowfax

    Joined:
    Mar 18, 2015
    Posts:
    38
    Yes I use NetworkIdentity ,Local Player Authority, true
    My question is about understanding,

    I understand how Local Player Authority works while using NetworkTransform, for example I tested an object movement using NetworkTransform

    Local Player Authority TRUE -> Move object on client syncs it on server cause Client has an Authority.
    Local Player Authority FALSE-> Moving on client does not sync on server, and moving on server syncs the client.

    But please explain how can I use Local Player Authority for other properties/methods on controlling player object while not using NetworkTransform....

    For example how can I perform the test I made before but with a GetComponent<Renderer>().material.color to test Authority:
    Local Player Authority TRUE -> I change color on client and it syncs to server cause it has an authority
    Local Player Authority FALSE -> I change color on clien and it doesn't sync to server, but when change on server it syncs to client.
     
    wlwl2 likes this.
  4. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    The quickest implementation would look something like this...
    Code (CSharp):
    1. void Update()
    2. {
    3.      if(!isLocalPlayer)
    4.           return; //THIS STOPS ANYONE THAT ISN'T THE LOCAL PLAYER FROM BEING ABLE TO
    5.                      //DO ANYTHING PAST THIS POINT OF THE UPDATE FUNCTION.
    6.  
    7.      if(Input.GetKeyUp(KeyCode.SPACE))
    8.           GetComponent<Renderer>().material.color = new Color(255, 255, 255, 255);
    9.  
    10. }
    However, the smarter way involves a bit more work. This script is disabled by default on the player prefab. You would "enable" this script when the player joins the match. That way if you have a game of 16 players, each player's machine doesn't have 16 of these scripts unnecessarily running Update().
     
  5. iShadowfax

    iShadowfax

    Joined:
    Mar 18, 2015
    Posts:
    38
    isLocalPlayer has nothing with Player Authority...
     
  6. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    "isLocalPlayer" returns true for the GameObject currently assigned to a single client. A client can only be assigned to a single GameObject at a time. A client can have authority over multiple GameObjects, but the clients presence in the scene is only ever on ONE GameObject. That GameObject will always return true from "isLocalPlayer". Even if that player has authority over 5 GameObjects, only one represents them at a time. So saying, "isLocalPlayer has nothing (to do) with Player Authority..." is wrong.

    Now...movin forward, you can use:
    Code (CSharp):
    1. if(hasAuthority)
     
  7. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
  8. iShadowfax

    iShadowfax

    Joined:
    Mar 18, 2015
    Posts:
    38
  9. iShadowfax

    iShadowfax

    Joined:
    Mar 18, 2015
    Posts:
    38
    My question:
    For example how can I perform the test I made before but with a GetComponent<Renderer>().material.color to test Authority:
    Local Player Authority TRUE -> I change color on client and it syncs to server cause it has an authority
    Local Player Authority FALSE -> I change color on clien and it doesn't sync to server, but when change on server it syncs to client.
     
  10. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    Wow. I've given you the answers. If you can't figure it out from there then you might not be cut out to write code for an online multiplayer game.
     
  11. iShadowfax

    iShadowfax

    Joined:
    Mar 18, 2015
    Posts:
    38
    Maybe you are a bad teacher?

    When using UNET and instanciate an object as a Player we have 2 instances:
    1) Client instance that is on client
    2) Server instance that is on server

    We use syncVars while setting them on server to sync them with client.
    We use [command] to run code on server player object and call it from client.

    If client has no authority of it's object than we can only modify it from server and sync with client via syncVars.

    My question is: If client has an authority on his server object how can we sync server properties from client?
     
    ethanxiaogptt and keatona like this.
  12. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    No. You just don't comprehend the documentation or what I'm trying to say to you. This will be the last attempt I make at HELPING YOU.

    Wrong. The instance is the same on both the Client and the Server. The only difference is who hasAuthority and which isLocalPlayer. All other relative data is exactly the same on both Client and Server at the time of spawning (via either NetworkServer.Spawn() or NetworkServer.SpawnWithClientAuthority()).

    This is correct.

    50% correct. 50% wrong. If a Client does not have authority they are unable to directly influence that GameObject. This does NOT, however, mean that the server can either. Only the Client (remember now, the Server is a Client as well) that hasAuthority can influence the GameObject. This has NOTHING to do with SyncVar. SyncVar simply sends any changes to a variable from the Server to all connected Clients for that particular GameObject. The Server does not have to have authority over a GameObject in order to synchronize its variables.

    You can't SYNC anything FROM the Client. SYNC'ing ONLY comes from the Server. If your Client hasAuthority it is allowed to send Commands. If it does NOT have authority, it is NOT allowed to send Commands. Use a Command to tell the Server to change to property.

    Good luck.
     
  13. iShadowfax

    iShadowfax

    Joined:
    Mar 18, 2015
    Posts:
    38
    Thank you for an explanation.
    I try to test this but if I turn off local client authority on NetworkIdentity and try to send command from client to dedicated server it works the same as if hasAuthority os off...
     
  14. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    Did you mean to say, "...it works the same as if hasAuthority is on..."?
     
  15. iShadowfax

    iShadowfax

    Joined:
    Mar 18, 2015
    Posts:
    38
    Yes, I can call command whenever Local Player Authority is on or off
     
  16. jathrek

    jathrek

    Joined:
    Jul 16, 2015
    Posts:
    36
    If you don't mind me interrupting, I had a question about some best practices related to this topic;

    How would you make the server forcefully "respawn" (move the position back to the network spawn) the player object (on which the local player has authority) when this one "dies" (following the game logic)? Basically, how to move back the player's object to starting point when it's health points get to 0?

    I'm currently thinking of two ways;
    • Monitor the player object from the client and handle the respawn at that level (meaning that it's not the server doing the modifications to the player object's position). But is it adequate to leave that responsability to the client?
    • Have the server create a new player object instance and replace the old one by that new one with NetworkServer.ReplacePlayerForConnection(...). In that case, the server is doing the job, but you end up creating a brand new object and throwing the old one away, which could require some kind of synchronization (by example, if the player's score was stored at the level of the player object, you'll need to copy it from the old one to the new one).
    Is there any other way? Is one of these ways better than the others for some reason or does it always depend on the project/game logic itself?


    Thank you!
     
  17. GixG17

    GixG17

    Joined:
    Aug 18, 2013
    Posts:
    105
    While you can't syncVar to the server, you can definitely send an RPC from the client to tell the server that the client's GameObject is of a particular color.

    Correct me if I'm wrong but I think the way to do it is:

    NetworkManager:

    Code (csharp):
    1.  
    2. [syncVar]
    3. Vector3 theColor = new Color(0,0,0);
    4.  
    5. [Command] Cmd_HasAuthority() {
    6.      theColor = new Color(1,1,1);
    7. }
    8.  
    ClientObject:

    Code (csharp):
    1.  
    2. void Update()
    3. {
    4.      GetComponent<Renderer>().material.color = NetworkManager.theColor;
    5.      if(!isLocalPlayer)
    6.           return;
    7.  
    8.      NetworkManager.Cmd_HasAuthority();
    9. }
    10.  
     
    Last edited: Dec 14, 2015
  18. iShadowfax

    iShadowfax

    Joined:
    Mar 18, 2015
    Posts:
    38
    Yes its right but what Is strange that if you change NetworkIdentity property of a player object to LocalPlayerAuthority false, you can still send the same command to the server.
     
  19. jathrek

    jathrek

    Joined:
    Jul 16, 2015
    Posts:
    36
    I suppose the player object is a special type of object for which the player will always have the right to send a command.
    From the help: "Commands are sent from player objects on the client to player objects on the server. For security, Commands can only be sent from YOUR player object, so you cannot control the objects of other players.".

    I think authoritative is more related to "who can change the transform of an object; the server or a client?".
    It seems to be confirmed by the part "Players, Local Players and Authority" of http://docs.unity3d.com/Manual/UNetConcepts.html

    So;
    • Local player (player prefab); the player has the right to send commands
    • Authority; the actor (server/client) has the right to modify the transform of the game object.
    By example, a local player object without authority would be controlled by sending CmdMove-like commands to the server, but local player object with authority would be controlled by modifying directly the transform at the level of the client (but you can still send commands to handle other things).
     
    Last edited: Dec 15, 2015
  20. iShadowfax

    iShadowfax

    Joined:
    Mar 18, 2015
    Posts:
    38
    All these suggestions probably show that there is a bug in NetworkIdentity Local player authority.
    It seems that it only works with NetworkTransform component. But it was designed, as said in documentation for other things too.
    It seems to me that a correct behaviour should be: if LocalPlayerAuthority=true than all properties of NetworkBehaviour object should be replicated to ots server side representation. As it is with NetworkTransform.

    Can anyone confirm that it's a bug?
     
  21. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
  22. jathrek

    jathrek

    Joined:
    Jul 16, 2015
    Posts:
    36
    seanr, how is managed the update on the server of a local player object (with authority at the level of the client) if that client modifies directly its transform? I suppose that these changes are sent to the server, through some internal mechanisms?

    But what are the specs of such a mechanism? What's the frequency of the updates sent to the server? Or is it using commands internally?

    *After typing these questions, I found more stuff in the manual*

    From this page (http://docs.unity3d.com/Manual/UNetConcepts.html), it seems that its related to how the NetworkTransform is set up;

    "In addition to isLocalPlayer, a player object can have “local authority”. This means that the player object on its owner’s client is responsible for the object - it has authority. This is used most commonly for controlling movement, but can be used for other things also. The NetworkTransform component understands this and will send movement from the client if this is set. The NetworkIdentity has a checkbox for setting LocalPlayerAuthority."

    That would means that, for the update of a local player object with client-authority, an update would have to go first to the server (so one NetworkTransform "cycle") then to the other clients, which makes it at least 2 NetworkTransform "cycles" (which means not faster than 2/29 of a second, which is actually very fast anyway)? In comparison to that, how fast would the information be sent to the server if a Command was used instead (so no client-authority)? Would it the server more quickly updated in that second scenario? Would that difference be sufficient enough to make it interesting to move the movements of a player object to the server? Could it also be relevant to use ClientRpc to propagate the updates of a player object (which can sometimes be much more unpredictable than an AI object) to other players?

    I don't think that knowing the details is really crucial, I'm mainly asking out of curiosity. ;-p
     
    Last edited: Dec 15, 2015
  23. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
  24. iShadowfax

    iShadowfax

    Joined:
    Mar 18, 2015
    Posts:
    38
    Now it's clear! Thank you! So HLAPI doesn't use commands, it uses messages from client to server, then server checks server object representation for local player authority and if it's true than performs updates.

    HLAPI implements commands so using command you have local player authority of object by default. Is it correct?

    From source code I see it uses netID to find object on server and it gets ID from a client message , but how does it check that this is an exact client that has an authority? Any client can send a message with netId for the same object
     
  25. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    Authority: http://docs.unity3d.com/Manual/UNetConcepts.html

    The ability for players to send commands is independent of localPlayerAuthority. Players can always send commands.

    Yes, NetworkMessages don't have the same security guarantees that are built into commands.

    But it is still possible to verify the source of messages. A NetworkConnection has HashSet of players and clientAuthority objects that it "owns". NetworkConnection.clientOwnedObjects. If a message is recieved from a netId that is not in this set, then it is from the wrong client.