Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

Question Client-owned NetworkBehaviour does not receive NetVar OnValueChanged callback

Discussion in 'Netcode for GameObjects' started by WakingDragon, Mar 18, 2023.

  1. WakingDragon

    WakingDragon

    Joined:
    Mar 18, 2018
    Posts:
    41
    I am spawning a NetworkObject with client ownership, and trying to subscribe to changes to a NetworkVariable (for the player name), but the client-machine instances are not receiving the OnValueChanged callbacks.

    The object is spawned correctly with the right ownership.
    The NetworkVariable is set to owner write permissions and everyone read permission.
    The NetworkVariable value gets updated on all instances and I can read them on each client.
    But the client does not receive the callback.

    I am trying to create a UI (not a networkobject) where players details are shown, but players can change their details and these get live propagated to all machines. The OnValueChanged callback is very helpful to update the UI only when there are new values to show.

    Any clues why?

    Code (CSharp):
    1. public class KingdomsNetworkPlayer : NetworkBehaviour
    2.     {
    3.         #region vars
    4.         private NetworkVariable<FixedString64Bytes> m_playerName = new NetworkVariable<FixedString64Bytes>(new FixedString64Bytes("New Player"), NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner);
    5.         public string PlayerName => m_playerName.Value.ToString();
    6.         public void SetPlayerName(string newName)
    7.         {
    8.             var newValue = new FixedString64Bytes(newName);
    9.             if(newValue != m_playerName.Value) m_playerName.Value = newValue;
    10.         }
    11.  
    12.         private NetworkVariable<int> m_playerNum = new NetworkVariable<int>(0, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner);
    13.         public int PlayerNum => m_playerNum.Value;
    14.         public void SetPlayerNum(int num) => m_playerNum.Value = num;
    15.         #endregion
    16.  
    17.         public override void OnNetworkSpawn()
    18.         {
    19.             base.OnNetworkSpawn();
    20.          
    21.             m_playerName.OnValueChanged += OnPlayerNameChangedEvent;
    22.             m_playerNum.OnValueChanged += OnPlayerNumChangedEvent;
    23.  
    24.             if (IsOwner)
    25.             {
    26.                 KingdomsApp.Inst.ReadyToLaunchLobby(); //NB: This just triggers a lobby-style UI
    27.  
    28.                 if (IsHost)
    29.                 {
    30.                     m_playerNum.Value = 1;
    31.                 }
    32.                 else
    33.                 {
    34.                     m_playerNum.Value = 2;
    35.                 }
    36.                //NB: This is the client-side singleton that updates a local list of player entities
    37.                 KingdomsApp.Inst.playerManager.UpdateLocalAndNetworkPlayers(this, true);
    38.             }
    39.             else
    40.             {
    41.                 KingdomsApp.Inst.playerManager.UpdateLocalAndNetworkPlayers(this, false);
    42.             }
    43.         }
    44.  
    45.         public override void OnNetworkDespawn()
    46.         {
    47.             base.OnNetworkDespawn();
    48.             m_playerName.OnValueChanged -= OnPlayerNameChangedEvent;
    49.             m_playerNum.OnValueChanged -= OnPlayerNumChangedEvent;
    50.         }
    51.  
    52.         private void OnPlayerNameChangedEvent(FixedString64Bytes previousValue, FixedString64Bytes newValue)
    53.         {
    54.             KingdomsApp.Inst.playerManager.UpdateLocalAndNetworkPlayers(this,IsOwner);
    55.         }
    56.  
    57.         private void OnPlayerNumChangedEvent(int previousValue, int newValue)
    58.         {
    59.             KingdomsApp.Inst.playerManager.UpdateLocalAndNetworkPlayers(this,IsOwner);
    60.         }
    61.     }
     
    Last edited: Mar 18, 2023
  2. Evil-Otaku

    Evil-Otaku

    Joined:
    Oct 17, 2012
    Posts:
    79
    The Owner client will not get the callback. It's assumed that it already knows it has changed its own value.
     
  3. WakingDragon

    WakingDragon

    Joined:
    Mar 18, 2018
    Posts:
    41
    Thanks for replying. I should have been clearer about my question: the client machines are not receiving callbacks from the host/server. The client receives his own callbacks, and the server receives callbacks from host and clients. But the client is not getting the server callbacks. Maybe the server netvar onvaluechange events are happening before the client NetworkObject is fully spawned?
     
  4. WakingDragon

    WakingDragon

    Joined:
    Mar 18, 2018
    Posts:
    41
    The workaround that I have ended up using is to trigger the client machines to re-read all the netvars when they get their own callbacks. I am only doing a boardgame so this level of fudging is passable, but it still seems pretty hokey/quirky to me.