isLocalPlayer returns false when Clients join.

When the player host(server + client) the server, everything works fine. However, after another player joins. isLocalPlayer returns to false and both character moves at the same time.

Here’s the movement code:

using Mirror;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement : NetworkBehaviour {
    // Variables
    public float normalSpeed;
    public float gravity;

    [SerializeField]private CharacterController controller;

    Vector3 velocity;

    private void Start() {
        if (!isLocalPlayer) { print(isLocalPlayer); }

        controller = GetComponent<CharacterController>();
    }

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

        if (isLocalPlayer) {
            callMovement();
        }
    }

    [Command]
    private void callMovement() {
        handleMovement();
    }

    [ClientRpc]
    private void handleMovement() {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");

        Vector3 move = transform.right * x + transform.forward * z;

        controller.Move(move * normalSpeed * Time.deltaTime);

        velocity.y += gravity * Time.deltaTime;

        controller.Move(velocity * Time.deltaTime);
    }
}

I’ve added NetworkIdentity and NetworkTransform on the prefab, also turned on Client Authority. Still don’t know why it doesn’t works.

This code is really really weird how you’re doing this.

So think about what is happening here. “isLocalPlayer” is only true on the host/client which this Player object represents. So when Update is called, and isLocalPlayer is true, then you call the Command callMovement(). When that happens either the local host immediately calls if for itself, or the client which owns this Player object tells the host to call it.

At that point callMovement() is run on the host, but all it does is call the ClientRpc handleMovement(). A ClientRpc is run on EVERY CLIENT, regardless of if they own this object or not. So every single client and the host all are running handleMovement separately for every single Player object. In handleMovement() you then take the local input and apply that to the character controller. So every client is using its local input to move around every Player object, no matter if they own that object or not. No don’t do this.

Then whether that gets synced depends on your NetworkTransform settings (assuming you have one), and if Client Authority is turned on or not. If Client Authority is true, then the movement on just that one Player object the client owns is then synced to the host, which is supposed to be then synced to the other clients. But as already mentioned you have every computer controlling every Player object, so you’re getting conflicting inputs for every object.

What you should do is just check for isLocalPlayer in Update, and if true you either send a Command with the inputs as parameters to the host for the host to move the Player (if using host authority), or if client authority you move the player locally and let the Network Transform sync the movement. None of this having the client tell the host to tell the client to capture input nonsense. Good luck

1 Like