Noob Question: Sharing NetworkPlayer instances

Hey everyone, noob here working on a Unity project for a school final project. I'm developing a multiplayer VR game using Netcode. The issue I'm having is that when a player is added to the dictionary in the NetworkGameManager class, then the debug log states that the size of the dictionary is always one no matter how many players join or leave the game lobby. Any help would be greatly appreciated!

NetworkGameManager class:

public class NetworkGameManager : NetworkManager
    {
        private Dictionary<Guid, NetworkPlayer> _playerIdToPlayer = new();

        public bool ContainsPlayer(Guid playerId)
        {
            var contains = _playerIdToPlayer.ContainsKey(playerId);
            Debug.Log("[NetworkGameManager] Player with id " + playerId + "is in dictionary: " + contains);
            return contains;
        }

        public Guid AddPlayer(NetworkPlayer player)
        {
            var playerId = Guid.NewGuid();
            Debug.Log("[NetworkGameManager] Adding player with id " + playerId + "to dictionary");

            _playerIdToPlayer.Add(playerId, player);
            Debug.Log("[NetworkGameManager] Total players after adding player " + _playerIdToPlayer.Count);
            return playerId;
        }

        public void RemovePlayer(Guid playerId)
        {
            Debug.Log("[NetworkGameManager] Removing player with id " + playerId + "from dictionary");
            _playerIdToPlayer.Remove(playerId);
            Debug.Log("[NetworkGameManager] Total players after removing player " + _playerIdToPlayer.Count);
        }

        public NetworkPlayer GetPlayer(Guid playerId)
        {
            Debug.Log("[NetworkGameManager] Getting player with id " + playerId + "from dictionary");
            return _playerIdToPlayer[playerId];
        }
    }

NetworkPlayer class:

public class NetworkPlayer : NetworkBehaviour
    {
        private const int MaxLives = 3;

        [SerializeField] public NetworkPlayerHealthScript healthScript;
        [SerializeField] public Transform root;
        [SerializeField] public Transform body;
        [SerializeField] public Transform head;
        [SerializeField] public Transform leftHand;
        [SerializeField] public Transform rightHand;
        [SerializeField] public Renderer[] meshToDisable;

        [SerializeField] public int team;
        [SerializeField] public NetworkVariable<int> lives = new(MaxLives);

        private Guid _playerId;

        public override void OnNetworkSpawn()
        {
            Debug.Log("[NetworkPlayer] On network spawn called");
            base.OnNetworkSpawn();
            if (!IsOwner)
            {
                Debug.Log("[NetworkPlayer] Not owner so returning early");
                return;
            }

            Debug.Log("[NetworkPlayer] Owner so enabling meshes");
            foreach (var mesh in meshToDisable)
            {
                mesh.enabled = false;
            }

            healthScript.SubscribeToHealthValue(OnHealthChange);

            var gameManager = NetworkManager.Singleton.GetComponent<NetworkGameManager>();
            _playerId = gameManager.AddPlayer(this);
        }

        public override void OnNetworkDespawn()
        {
            Debug.Log("[NetworkPlayer] On network despawn called");
            base.OnNetworkDespawn();
            if (!IsOwner)
            {
                Debug.Log("[NetworkPlayer] Not owner so returning early");
                return;
            }

            Debug.Log("[NetworkPlayer] Owner so disabling meshes");
            foreach (var mesh in meshToDisable)
            {
                mesh.enabled = true;
            }

            var gameManager = NetworkManager.Singleton.GetComponent<NetworkGameManager>();
            gameManager.RemovePlayer(_playerId);
        }


        public Guid GetPlayerId()
        {
            return _playerId;
        }

        public float GetHealth()
        {
            return healthScript.GetHealth();
        }

        public void SetHealth(int health)
        {
            healthScript.SetHealth(health);
        }

        public void TranslateHealth(int health)
        {
            healthScript.TranslateHealth(health);
        }

        public bool IsDead()
        {
            return healthScript.IsDead();
        }

        private static void OnHealthChange(int previousValue, int newValue)
        {
            Debug.Log("[NetworkPlayer] Health changed from " + previousValue + " to " + newValue);
            VRRigReferences.singleton.healthbarImage.fillAmount = (float)newValue / NetworkPlayerHealthScript.MaxHealth;
            VRRigReferences.singleton.healthbarText.text = "Health: " + newValue;
        }

        private void Update()
        {
            if (!IsOwner) return;

            var reference = VRRigReferences.singleton;

            SetTransform(root, reference.root);
            SetTransform(body, reference.body);
            SetTransform(head, reference.head);
            SetTransform(leftHand, reference.leftHand);
            SetTransform(rightHand, reference.rightHand);
        }

        private static void SetTransform(Transform toSet, Transform setFrom)
        {
            toSet.position = setFrom.position;
            toSet.rotation = setFrom.rotation;
            toSet.localScale = setFrom.localScale;
        }
    }

Hi,

I see a problem inside your method AddPlayer() of the NetworkGameManager class. When you try to add a player, you're using the default Guid as the player id. I believe what you want to do is to retrieve the player id from your NetworkPlayer by doing :

var playerId = player.GetPlayerId();

Of course, don't forget that player could be null in some case, and that this line could lead to an error in this case.

Hope this helps !