Why players who join late can't see other people data?

I want to show the name of the players above their head but I have a problem where people joining late doesn't get other players' name.

For example:

• Player 1 joins to the server with the name Peter.
• Player 2 joins to the server with the name Josh.
• Peter (Player 1) sees Josh's name perfectly, but when Josh joins Peter's name is not synchronized correctly.

My sync code looks something like this:

[SyncVar] private string NAME;
public override void OnStartClient(){
if(networkPlayerData is null)
{
networkPlayerData = BTNetworkController.Controller.playerData;
NAME = BTNetworkController.Controller.playerData.Name;
}
SendPlayerNameToServer(NAME);
}
[Command]
private void SendPlayerNameToServer(string name)
{
RpcSetPlayerName(name);
}

[ClientRpc]
void RpcSetPlayerName(string name)
{

gameObject.GetComponentInChildren<TMP_Text>().text = name;
}


So my question is how can I sync data to newly joined players and refresh player names accordingly.

Do not use NAME and name, it makes things confusing and you might write to the wrong variable at times. Give it more fitting names, like playerName, localName, nameToUpdate or similar. All caps is usually used for constants.

Your SendPlayerNameToServer is using wrong naming, since it is a Command, it has to start with Cmd for Mirror to work correctly. Therefore CmdSendPlayerNameToServer is the correct name. Command docu

[SyncVar] does not need a ClientRpc, you can set them on the server and they get synced automatically. In case you want to react to a change of the name, you could use a hook that reacts to the change. Hook docu

[SyncVar(hook = nameof(SetPlayerName))]
private string playerName;

void SetPlayerName(string oldName, string newName)
{
gameObject.GetComponentInChildren<TMP_Text>().text = newName;
}


Since your code contains a OnClientStart(), which should be part of the NetworkManager and not the Player, here is a small example for a player script that you can add to the Player Pref and add it to the NetworkManager under Player.

public class Player: NetworkBehaviour
{
[SyncVar] public string playerName;

void Start()
{
//we are only setting the name from the place that owns the player.
if (hasAuthority)
{
CmdRegisterPlayer();
}
}

[Command]
private void CmdRegisterPlayer(){
playerName = "Player " + Random.Range(0, 100);
}
}

• Comments are not for extended discussion; this conversation has been moved to chat. Mar 2 '21 at 15:30