Search Unity

Question Network Variable Structs

Discussion in 'Multiplayer' started by moproductions, Mar 14, 2024.

  1. moproductions

    moproductions

    Joined:
    Sep 28, 2010
    Posts:
    88
    Thanks to folks being so helpful here I've managed to sort out what I needed with Rpc's and re-parenting, etc. When moving onto NetworkVariables I was able to get that to sync easily just by using the .Value on the server and the client was seeing it fine.
    However, I'm now trying to network sync a struct and I'm getting lost again. Here's my struct and how I'm using it:

    Screenshot 2024-03-14 170759.png

    So I call GameInfo.UpdateState(...) in the normal game logic, assuming that making those changes would somehow trigger the NetworkSerialize() part and all would be taken care of. However, no matter what I do I can't get it to sync with the client. I have a feeling making all the enums NetworkVariables and changing their .Value would do it but I thought that using iNetworkSerializable structs it would take care of itself. Is there something else I need to do to get this struct to get updated on the client side? Perhaps a way to get the NetworkSerialize function to get triggered?
    Any help is appreciated, I'm almost done cracking this networking stuff.
    Thanks!
    -Mike
     
    Last edited: Mar 14, 2024
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    666
    Changes to the struct won't automagically be picked up when implementing INetworkSerializable. You'll have to either have the struct as a NetworkVariable field or pass it via an RPC. It's through these that the NetworkSerialize() method will be called.

    Here's a quick example:
    Code (CSharp):
    1.    public class Player : NetworkBehaviour
    2.     {
    3.         [SerializeField] NetworkVariable<StateInfo> stateInfo = new NetworkVariable<StateInfo>();
    4.  
    5.         public override void OnNetworkSpawn()
    6.         {
    7.             base.OnNetworkSpawn();
    8.  
    9.             stateInfo.OnValueChanged += OnStateInfoChanged;      
    10.         }
    11.  
    12.         private void Start()
    13.         {
    14.             if (IsServer)
    15.             {
    16.                 // update as a NetworkVariable, note it must be a new instance of the struct
    17.                 stateInfo.Value = new StateInfo(GameState.Running);
    18.  
    19.                 // or
    20.  
    21.                 // send update as an RPC
    22.                 UpdateGameStateClientRpc(new StateInfo(GameState.Ended));
    23.             }
    24.         }
    25.  
    26.         [ClientRpc]
    27.         public void UpdateGameStateClientRpc(StateInfo stateInfo)
    28.         {
    29.             Debug.Log("Player UpdateGameStateClientRpc stateInfo gameState: " + stateInfo.GameState);
    30.         }
    31.  
    32.         private void OnStateInfoChanged(StateInfo oldStateInfo, StateInfo newStateInfo)
    33.         {
    34.             Debug.Log("Player OnStateInfoChanged new gameState: " + newStateInfo.GameState);
    35.         }
    36.     }
     
  3. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,012
    Check what the Value property in NetworkVariable.cs does. It‘s what you would need to do in your UpdateState method. Be sure to send out only actual changes. And check your enums are using the smallest possible type, most enums are just a byte but default to int (4 bytes) unless you specify a type.
     
  4. moproductions

    moproductions

    Joined:
    Sep 28, 2010
    Posts:
    88
    Thank you for the tips, crew! I got sidetracked the last couple of days workng on a demo but will be back on this shortly. Looking forward to it...