Player Movement in Multiplayer Game

Hi guys, I have a quick question. I have been creating a multiplayer fps game and now I am working on player movement script. I encountered a problem. The problem is client move faster. But host move normally. Here is my player movement code.

[SerializeField] float movementSpeed = 0.03f;
[SerializeField] Vector3 movement;

#region Server

[Command]
private void CmdMove(Vector3 movement)
{
    transform.position += movement * movementSpeed;
}

#endregion

#region Client

[ClientCallback]
private void Update()
{
    if (!hasAuthority) { return; }

    if (!Input.anyKey) { return; }

    Movement();
}

private void Movement()
{
    float xAxis = Input.GetAxis("Horizontal");
    float zAxis = Input.GetAxis("Vertical");

    movement = new Vector3(xAxis, 0, zAxis);

    CmdMove(movement.normalized);
}

#endregion

Hi there,
You movement is not independent of frame rate. So whichever game has higher frame rates, that player will move faster. Use Time.DeltaTime to adjust your movement to the framerate.

Ah, actually I used Time.DeltaTime I copied the wrong one, but I used it in the client side Should I use it in the server I mean in the CmdMove function ?

It’s best practice to execute the movement code on the server. You can do the calculation there, and the actual movement. Then use the NewtowrkTransform to sync it back to the clients. If all the calculations and movement are done on the server, it will guarantee they are the same on each client.

Okay thank you. Now my new script looks like this;

public class PlayerMovement : NetworkBehaviour
{
[SerializeField] float movementSpeed = 3.5f;
[SerializeField] Vector3 movement;

#region Server

[Command]
private void CmdMove(float xAxis, float zAxis)
{
    movement = new Vector3(xAxis, 0, zAxis);

    transform.Translate(movement.normalized * movementSpeed * Time.deltaTime);
}

#endregion

#region Client

[ClientCallback]
private void Update()
{
    if (!isLocalPlayer) { return; }

    if (!Input.anyKey) { return; }

    Movement();
}

private void Movement()
{
    float xAxis = Input.GetAxis("Horizontal");
    float zAxis = Input.GetAxis("Vertical");

    CmdMove(xAxis, zAxis);
}

#endregion

}

I hope I implemented as you said. Let me know if you see anything weird :).

I would like to mention that I use ParrelSync, I do not want to build and run the game again again again…

Now this code works fine when I use the ParrelSync but when I build the game and run, client move faster again. I do not know what the problem is.

The code looks good. Are you using the same input device to test the client and the server? Shouldn’t matter because you are normalizing the input, but thought I’d check.

Yes , I use the same input device to test. I changed the code and click the “Client Authority” in the Network Transform component and now it works well. All character move in the same speed.

Here is the code;

[SerializeField] float movementSpeed = 3.5f;
Vector3 movement;

#region Server

//[Command]
//private void CmdMove(float xAxis, float zAxis)
//{
//    movement = new Vector3(xAxis, 0, zAxis);

//    transform.Translate(movement.normalized * movementSpeed * Time.deltaTime);
//}

#endregion

#region Client

[ClientCallback]
private void Update()
{
    if (!isLocalPlayer) { return; }

    if (!Input.anyKey) { return; }

    Movement();
}

private void Movement()
{
    float xAxis = Input.GetAxis("Horizontal");
    float zAxis = Input.GetAxis("Vertical");

    movement = new Vector3(xAxis, 0, zAxis);

    transform.Translate(movement.normalized * movementSpeed * Time.deltaTime);
}

#endregion

}

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms