UNET Would be nice to be able to "switch" authority from one client to another

I’m using spawnwithAuthority to give players the ability to drive vehicles smoothly but I’d also like to switch them out… the only way I can see doing that now is to spawn a new vehicle when the player “gets in” (touches its trigger collider) and despawning it when he gets out, and replacing it with a server controlled one… then when the other player touches it, spawnwithAuthority replace it with that one.

Am I making any sense?

I was also wondering about it. I would prefer everything to be server controlled (multiple player objects), but as for now it’s not possible - and so when my player’s ships module gets destroyed, it gets deattached, and I want player to lose control over it then - so pass authority to server.

NetworkIdentity.AssignClientAuthority()

2 Likes

OMG THAT WORKS PERFECTLY!!! THANK YOU SO MUCH!!!
/developer hug

1 Like

SEAN!!! I think I found a bug with this. I just had 2 guys connect to my game and try it because I needed to make sure it is what I thought it is.

Basically… when a client “takes authority” of the car, it ROCKS… the car moves and I see it go on the host. He presses “L” to get out, and that calls “RemoveClientAuthority” … the OTHER client gets in… takes off and it ROCKS… everything is working perfect. He presses “L” and removes his authority. BUT… now “I” (the HOST) get in, and I AssignClientAuthority with my host connection and the car MOVES ON MY SCREEN but the NetworkTransform no longer updates the clients with the new position! OH NOES!!! I’m SO CLOSE MAN THIS IS KILLING ME. :smile:

Hm. setting authority to a local client connection is an interesting use case. I would not be surpised if that had not been tested.

There is also NetworkIdentity.RemoveClientAuthority() which reverts control back to the server, but that is not quite the same as assigning authority to the local client on the host.

The problem could possibly be then that I’m calling NetworkIdentity.AssignClientAuthority() with the HOST connection and that is what is making it “break”… I could try it without that call except I don’t know an easy way to “know” if I’m a host and not a client when the player object hits the cars trigger collider. In my mind it should be “ok” to call that function with the host ID though, so I appreciate you looking into it. :wink:

I tried checking for “isClient” but that returns true even from the host player.

Ahh… Host IDtoClientConnection is always “-1”?

Bug 728735 filed on this. Should be fixed in an upcoming patch release.

2 Likes

SWEET! I was just going to tell you that without using the “AssignClientAuthority” from the host connection the host can’t control it even though the client removed the authority.

How did you manage to use “NetworkIdentity.AssignClientAuthority()” ? Can you give an example code please ?

I read the doc but there arent any examples how to use this…

thanks

I don’t have my notebook computer on me but as soon as I get home from work in 6 hours, I promise I’ll show you how I did it.

Thanks very much, i will be looking forward for your answer. Thats the only issue left that i should solve :slight_smile:

Also interested in this. Going to test the new patch to see if I can change authority from host to client and keep it that way.

So… on my “server spawned object” (in this case a car) I have a script that handles the trigger collision with the player… when the player collides the script calls a function on a script that is attached to the player object:

void OnTriggerEnter(Collider other)
{

if (other.gameObject.tag == “Player”)
{
other.gameObject.GetComponent().DisablePlayerEnableCar();

}
}

The script SwitchControllers attached to the players, DisablePlayerEnableCar does some activating/deactivating of components but the first thing we’re interested in for this thread is here:

public void DisablePlayerEnableCar()
{
if (!isLocalPlayer)
return;
Debug.Log("IDs: " + this.GetComponent().connectionToServer.connectionId.ToString());

CmdServerAssignClient();
this.GetComponent().enabled = true;
}

The command to assign that connection looks like this:
[Command]
void CmdServerAssignClient()
{
GameObject CarServer = GameObject.Find(“AssaultVehicle”);
CarServer.GetComponent().AssignClientAuthority(this.GetComponent().connectionToClient);

}

When the player presses “L” the swtichcontroller switch calls this command to remove his authority:

[Command]
void CmdServerRemoveClient()
{
GameObject CarServer = GameObject.Find(“AssaultVehicle”);

CarServer.GetComponent().RemoveClientAuthority(this.GetComponent().connectionToClient);

}

So now… in order to “move the car” I have a PlayerCarController script on the player object, that applies the controls and sends those values to the Controller script attached to the vehicle. Without clientauthority this had to be a server command and that caused some “lag” from clients as well as a LOT of network traffic… instead now we’re directly calling our version of the “local car” and it’s sending it’s networktransform data up the wire to the server as expected:
void Start()
{
if (isLocalPlayer)
{
Car = GameObject.Find(“AssaultVehicle”);
CarScript = Car.GetComponent();
}
}
void FixedUpdate()
{
if (!isLocalPlayer)
return;

float Steer = Input.GetAxis(“Horizontal”);
float inputPower = Input.GetAxis(“Vertical”);

if(PreviousPower != inputPower || PreviousSteer != Steer)
{
CarScript.CarControl(Steer, inputPower);
// CmdCallCarScript(Steer, inputPower); // no longer needed with client authority
PreviousSteer = Steer;
PreviousPower = inputPower;
}

}

Thanks, this is going to be really helpfull.

1 Like

Thanks for your valueable code, seems it is working but showing me this error:

NullReferenceException: Object reference not set to an instance of an object
UnityEngine.Networking.NetworkTransform.SendTransform () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkTransform.cs:1103)
UnityEngine.Networking.NetworkTransform.Update () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkTransform.cs:1031)

I don’t where is the problem as it showing in UNet HLAPI. Can you see this?

Probably you have forget to check hasAuthority property before moving the player? Correct?