welcome to the GameDev Stack Exchange. It looks like your code currently only runs server side which is pretty normal for most projects when initially creating players and setting up the scene. This should keep your server up to date with the latest information, however it does not send these updates to clients.
Usually when setting shared variables you need to plan for sending updates to 1.) the server, 2.) clients already in game, 3.) new clients joining the game. Most online tutorials will help you with the first 2 but the 3rd case is usually the most difficult (you can do this by either resetting all player names when someone joins or by using [TargetRpc]).
An easy way to take care of this is using the [SyncVar] property which will send regular updates to every client/server about property updates. This can be helpful if a variable is constantly changing but as @DMGregory suggests, can be overkill in most cases. Usually in this scenario you will need to tell the server to let clients know the name has changed and that they should update their local version of the players name to match the new players name
Below is roughly what I would do to try an keep names synchronized (you may need to fiddle with it because like most code on StackExchanges, it isn't really properly tested and is just there to give you an idea of how to solve the problem). This may seem like a lot of code, but the idea is that by updating the players name only when needed you can keep your network connection free for sending more important updates like player positions.
using System.Collections.Generic;
using UnityEngine;
using Mirror;
public class MyNetworkManager : NetworkManager
{
public List<GameObject> spawnPos;
public override void OnServerAddPlayer(NetworkConnection conn)
{
Transform start = spawnPos[numPlayers].transform;
GameObject player = Instantiate(playerPrefab, start.position, start.rotation);
NetworkServer.AddPlayerForConnection(conn, player);
int playerId = PlayerManager.Instance.players.Count() - 1;
string name = "car_" + playerId.ToString();
PlayerManager.Instance.SetPlayerName(playerId, name);
}
}
public class PlayerManager : NetworkBehaviour
{
public PlayerManager Instance; // Quick and dirty singleton, you can find better implementations later
public List<Player> players = new List<Player>();
public void Awake()
{
Instance = this;
}
// Call this when you want to change a players name
public void SetPlayerName(int playerId, string name)
{
CmdSetPlayerName(playerId, name);
}
// Tell server name to let people know a name has changed
[Command]
private void CmdSetPlayerName(int playerId, string name)
{
players[playerId].SetPlayerName(name); // update my player name value
RpcSetPlayerName(playerId, name); // tell clients to update value
}
// tell client to update their own copy of the players name
[ClientRpc]
private void RpcSetPlayerName(int playerId, string name)
{
players[playerId].SetPlayerName(name); // update my player name value
}
}
public class Player : MonoBehaviour
{
private void Awake()
{
PlayerManager.players.Add(this);
}
// Actually update players name.
public void SetPlayerName(string name)
{
gameObject.name = name;
}
}