Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question Custom Struct Network Variable Not Detecting Changed Value

Discussion in 'Netcode for GameObjects' started by ponerboner, Aug 23, 2023.

  1. ponerboner

    ponerboner

    Joined:
    Jan 12, 2022
    Posts:
    3
    Hello, I am trying to sync a small player input buffer via a Network Variable. On the owning player, whenever they press/release a button, I capture it and update the Network Variable. The problem is that I use a custom struct, containing an array of another struct, which contains a byte representing the various player inputs being on/off, and a sequence number to avoid processing the same input multiple times.
    When I try to update the Network Variable, I need to create a new struct that takes in the new Input Buffer, and set it to the Network Variable. Otherwise just setting the value to the pre existing localPlayerInputBuffer will not trigger the Value Change event. Is there a better way? I do not want to create a new buffer every time a button is pressed.

    Code (CSharp):
    1. //Player Script
    2. public NetworkVariable<PlayerInputBuffer> PlayerInputBuffer =
    3.         new NetworkVariable<PlayerInputBuffer>(
    4.             new PlayerInputBuffer(new PlayerInputData[MAX_BUFFER_SIZE]),
    5.             NetworkVariableReadPermission.Everyone,
    6.             NetworkVariableWritePermission.Owner
    7.         );
    8. public PlayerInputBuffer localPlayerInputBuffer =
    9. new PlayerInputBuffer(new PlayerInputData[MAX_BUFFER_SIZE]);
    10.  
    11. public void CaptureInput(byte inputFlags)
    12. {
    13.     localPlayerInputBuffer.inputData[currentInsertIndex].inputFlags = inputFlags;
    14.     localPlayerInputBuffer.inputData[currentInsertIndex].sequenceNumber = currentSequenceNumber;
    15.     currentInsertIndex = (currentInsertIndex + 1) % MAX_BUFFER_SIZE;
    16.     currentSequenceNumber++;
    17.      
    18.     //need to instantiate a new PlayerInputData every time, otherwise the NetworkVariable will not detect a change
    19.     PlayerInputData[] newDataArray = new PlayerInputData[MAX_BUFFER_SIZE];
    20.     for (int i = 0; i < MAX_BUFFER_SIZE; i++){
    21.         newDataArray[i] = new PlayerInputData(
    22.         localPlayerInputBuffer.inputData[i].inputFlags,
    23.         localPlayerInputBuffer.inputData[i].sequenceNumber);
    24.     }
    25.     PlayerInputBuffer.Value = new PlayerInputBuffer(newDataArray);
    26. }
    Code (CSharp):
    1. //Custom Structs
    2. public struct PlayerInputData {
    3.     public byte inputFlags;
    4.     public byte sequenceNumber;
    5. }
    6. public struct PlayerInputBuffer : INetworkSerializable
    7. {
    8.     public PlayerInputData[] inputData;
    9. //serialization functions etc...
     
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    676
    Have a look at using NetworkList<PlayerInputData> and its OnListChanged event.
     
  3. ponerboner

    ponerboner

    Joined:
    Jan 12, 2022
    Posts:
    3
    Wow, changing it to a NetworkList and using OnListChanged fixed it for me. I didn't realize I had the option to use NetworkLists instead of NetworkVariables. Thank you!
     
    cerestorm likes this.