Okay, you lost me… I also thought about just moving the code into a separate function but, just like my own solution to get it working, it doesn’t explain why I need to.
The project that I am making does not use an authoritative server and is a simple case of one player being the host while the others are not. I have one object which is called by both players but I want the host to … okay well I guess I want the host to be authoritative. From what I read in the docs the Command attribute means that whichever player is calling that function, the host is the one that will execute it.
According to the example in the docs you can call them just like any other function, except it will be run on the server, always…
void Update()
{
if (!isLocalPlayer)
{
return;
}
// input handling for local player only
int oldMoveX = moveX;
int oldMoveY = moveY;
moveX = 0;
moveY = 0;
if (Input.GetKey(KeyCode.LeftArrow))
{
moveX -= 1;
}
if (Input.GetKey(KeyCode.RightArrow))
{
moveX += 1;
}
if (Input.GetKey(KeyCode.UpArrow))
{
moveY += 1;
}
if (Input.GetKey(KeyCode.DownArrow))
{
moveY -= 1;
}
if (moveX != oldMoveX || moveY != oldMoveY)
{
CmdMove(moveX, moveY);
}
}
[Command]
public void CmdMove(int x, int y)
{
moveX = x;
moveY = y;
isDirty = true;
}
So why exactly is it now that I can’t do what they show in the documentation and that I need to create a workaround for doing what they show? Here is anothe example of what I mean
public class Player : NetworkBehaviour
{
int moveX = 0;
int moveY = 0;
void Update()
{
if (!isLocalPlayer)
{
return;
}
// input handling for local player only
int oldMoveX = moveX;
int oldMoveY = moveY;
moveX = 0;
moveY = 0;
if (Input.GetKey(KeyCode.LeftArrow))
{
moveX -= 1;
}
if (Input.GetKey(KeyCode.RightArrow))
{
moveX += 1;
}
if (Input.GetKey(KeyCode.UpArrow))
{
moveY += 1;
}
if (Input.GetKey(KeyCode.DownArrow))
{
moveY -= 1;
}
if (moveX != oldMoveX || moveY != oldMoveY)
{
CmdMove(moveX, moveY);
}
}
[Command]
void CmdMove(int dx, int dy)
{
// move here
}
}
Both clients can call the same command but the code is always run on the server. Looking at the samples and based on what you replied, though, it SOUNDS to me like a normal method calling a command and a command calling a command is two completely different matters and it simply should not or cannot be done… but what about the case of a client pressing the Up arrow, this calls the command on the host and in response to the up arrow being pressed the host sends out an Rpc call to the client who pressed the button… does this mean that Commands can’t call Rpc functions either?
What I want to do is very simple indeed: Both clients can press the up arrow but doing so will change a value only on the client who is acting as host / server. That works just fine. Now In the case of my original post, all I want to do is say “You pressed the up arrow but the value is foo so instead of running this function I am going to pretend you pressed the down arrow and run THAT key’s associated function instead”. Obviously since I am still trying to change a value on the host only and this should never be run on normal clients, I figured just calling the Cmd that is called usually is the sensible thing to do… only I’m not allowed to. Why?
Clearly I am completely lost by this. Your solution is to create a workaround but my very question is “Why?”. It sounds like you are trying to explain that but my mind is having a hard time meshing what you are saying and what I am seeing in the examples provided by Unity where they teach us by example.
I simply don’t understand why Unity is saying “Methods marked as a command will be run on the server” and why you are saying “Commands will be treated as a message to the server so you should not call the command”… I don’t get it. That is exactly what I want to do, call the function on the server. Why must I NOT call the command on the server when I need to run the command on the server, but rather call it via a normal function that can be run on the client and server both, instead?
There are two players and one of them is the server so ONE of them will always run that code on themselves. It sounds like you are saying “When the player who is the host is trying to call the command, you can’t do that and shouldn’t do that”… yet isn’t that exactly how it is supposed to be done? What am I missing here? What is the missing piece that I am not seeing?