Authoritative walking.

Alright, I saw a number of scripts for players in authoritative servers. My code however has a little bit different structure than most of the ones I saw.

Now let me explain what problem am I experiencing and than I’ll show my code:
I initialize the server and I can walk and do everything with the server’s player. Than I connect a client to the server. When the client is spawned the server loses control over his player - can’t rotate it, can’t move it and can do nothing. The client can move his player, but except his player, the client moves the server’s player too. The client CAN look around with the mouse, but if I start walking, the rotation gets reset. Now here’s my code, I’ll just show a little just to show the idea of my script’s mecahnism:

First we have the owner setting:

@RPC 
function PlayerSetup(player : NetworkPlayer){
owner = player;
if(owner != Network.player) {
mine = false;
playerCamera.camera.enabled = false;
playerCamera.GetComponent(AudioListener).enabled= false;
}

This is called when the player is spawned.

Than we go to Update function and from here I separate the code in two parts - one for the authoritative server, that calculates all the motions, gravity, sliding and everything that is applied to the player no matter what. The other part is for the owner of the player, it takes the inputs from him:

function Update () {
//Things, that are dependant on what the user does
if(owner == Network.player) OwnerControl();

//Things like gravity, sliding off steap surfaces and others, that are applied no matter what
if(Network.isServer) ServerControl();
}

Now I’ll just show the main part of the OwnerControl so that I don’t get anyone confused:

function OwnerControl() {
button_fd = Input.GetButton("Forward");
button_bk = Input.GetButton("Backward");
button_lf = Input.GetButton("Left");
button_rt = Input.GetButton("Right");
button_duck = Input.GetButton("Duck");

//Rotation should be done on the player owner's machine
if(!weaponManager.turretMenu  !Menu.state){
transform.Rotate(0, Input.GetAxis ("Mouse X") * mouseSensitivity, 0); 
}

// Sending the movement input total 
if(Network.isServer){
if(!Menu.state)
CalculateMove(button_fd, button_lf, button_bk, button_rt, button_duck, sprinting);
else CalculateMove(false, false, false, false, false, false);
}


if(Network.isClient){
if(!Menu.state)
networkView.RPC("CalculateMove", RPCMode.Server, button_fd, button_lf, button_bk, button_rt, button_duck, sprinting);
else networkView.RPC("CalculateMove", RPCMode.Server, false, false, false, false, false, false);
} 


}

CalculateMove is the function, that calculates the movement variables, that are later used to move the player.

The function, that I won’t show is the ServerControl, which is used to actually move the player, apply gravity and everything. It’s using the CharacterController.Move function.

Can you help me out and tell me where am I wrong. I’m sure I’m missing something, but I don’t have a clue. The problem is that everything looks fine to me.

have you tried any debugging of your scripts ?

Yes, but everything seems fine… So you don’t see anything wrong with my structure? That’s odd.

did you debug the rpc call when a client connects ? what calls are sent to the client ?

Alright, I put more effor on the debugging this time and found something:
The server connects and everything’s alright, his number is set to 0, but when trying to set the clients number, the script fails:

In the spawner script:
This…

function Spawn(connectedPlayer : NetworkPlayer){
	var playerNumber : int = parseInt(connectedPlayer +"");
	print("Player is given the number  " + playerNumber);
	playerTransform = Network.Instantiate(playerObject, transform.position, transform.rotation, playerNumber);
	var playerNetworkView : NetworkView = playerTransform.networkView;
	print("Player has received the number and the number is " + playerNetworkView.group);
	playerNetworkView.RPC("PlayerSetup", RPCMode.AllBuffered, connectedPlayer);
	print("An RPC call is sent to the player, setting it's PlayerSetup function to " + connectedPlayer);
}

Outputs this:

Than in the player’s script:

This…

@RPC 
function PlayerSetup(player : NetworkPlayer){
owner = player;
print("The player has observed the setting and is now " + owner);
print("network player is " + Network.player);
if(owner != Network.player) {
mine = false;
playerCamera.camera.enabled = false;
playerCamera.GetComponent(AudioListener).enabled= false;
}
else mine = true;


}

Outputs this:

So no wonder my script is malfunctioning. I should have done this debug earlier, I had only done debugs on if statements and other things in the player. I was pretty sceptic that my spawner script is the wrong one, because it’s pretty short and I often mess up longer scripts :smile:

The problem is I don’t know where’s the problem now

EDIT: I think this is what is wrong:

It should be receiving the number 1, not 0.

Does anyone have an idea? I still can’t figure out how to fix this. I can also upload my code somewhere.

OK, I see nobody can tell what’s wrong from what I posted, so here’s my unfinished player script:

Please, someone take a look at it and tell me what’s wrong. I checked the spawner script and even replaced it with other spawning scripts and it all was the same, so I think the problem is in the player script.

Don’t fix the script, just tell me what I have done wrong.

Thanks in advance! :slight_smile:

433908–15082–$Player.js (5.5 KB)

"Player has received the number and the number is 0 ", the line you are having a problem with, is the network group. You didn’t set this to anything else, so it defaults to zero, the default network group.

What you think you’re setting the networkview.group to the player number, in the network.instantiate, is actually the group number of the RPC call for that network.instantiate (as all network.instantiates are buffered rpc calls actually). The networkview.group of the object instantiated does not follow this.

to set this, just after declaring playerNetworkView, just do:
playerNetworkView.group = playerNumber

I can’t remember if you actually will have to propagate this to the clients. Just do some debugging and see if they get the change.

Thanks for the reply. It didn’t work with the group setting. The group doesn’t get set no matter what. but I don’t think that I even check the group anywhere in the player script. I think the problem is with Network.player. I have debugged it and the console shows that both of the Network.players are 1 and this shouldn’t be happening. Do you think this could be the problem ?

EDIT: OK, I managed to set the player groups and debuged them. THey absorb the group numbers, but the problem still occours :frowning:

OK, I’ve been testing this script with other projects and stuff, where the spawners and everything are already made. The problem has got to be in the Player script, but four days passed and I still cannot figure out where is the problem. Can somebody please help me with this, I’ll even put the one, who helps me in the credits, because I did thousands of things in the game (I’ve been planning to make a post for in in the showcase section) and I don’t want to throw all this away, because of something, the answer to which might be fairly simple :frowning:
I really, really don’t know what else to do and to try… I’m all out of ideas and I truely hope someone will be able to help me out. I’m really sorry to bump this topic over and over again, I try all my bump posts to contain some useful information on my problem, but the problem is I can’t think of anything else to say