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 Help with INetworkSerializable and NetworkVariables

Discussion in 'Game Server Hosting' started by TxLoo, Jun 10, 2023.

  1. TxLoo

    TxLoo

    Joined:
    Jun 8, 2023
    Posts:
    1
    Hi, I am creating a multiplayer base, for future multiplayer games. So for starters, I am just testing out how network variables work with an array that inherits INetworkSerializable.

    Code (CSharp):
    1.  
    2. public struct PlayerDetails : INetworkSerializable
    3. {
    4.     public string name;
    5.  
    6.     // INetworkSerializable
    7.     public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    8.     {
    9.      
    10.         if (serializer.IsReader)
    11.         {
    12.             name = new string(name);
    13.         }
    14.         serializer.SerializeValue(ref name);
    15.     }
    16.     // ~INetworkSerializable
    17. }
    18.  
    19. public struct PlayersConnected : INetworkSerializable
    20. {
    21.     public PlayerDetails[] playerArray;
    22.     public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    23.     {
    24.         // Length
    25.         int length = 0;
    26.         if (!serializer.IsReader)
    27.         {
    28.             length = playerArray.Length;
    29.         }
    30.  
    31.         serializer.SerializeValue(ref length);
    32.  
    33.         // Array
    34.         if (serializer.IsReader)
    35.         {
    36.             playerArray = new PlayerDetails[length];
    37.         }
    38.  
    39.         for (int n = 0; n < length; ++n)
    40.         {
    41.             playerArray[n].NetworkSerialize(serializer);
    42.         }
    43.  
    44.     }
    45. }
    I am looking at https://docs-multiplayer.unity3d.com/netcode/current/advanced-topics/custom-serialization/,
    https://docs-multiplayer.unity3d.co...ed-topics/serialization/inetworkserializable/
    I have implemented the INetworkSerializable, but in Custom Serialization, it talks about having to extend the FastBufferWriter and Reader. I am confuse on how to implement that, and then it requires an addition of code in the start up of the program.

    I am trying to track the players connected via network variables. I know that there are other ways to do so, but I am trying to learn how to use network variables for any other future purposes. So i am trying to get a working example for custom class network serializable.

    Currently I have the above code, and the below code to try to get an array of players connected to see if it would work.


    Code (CSharp):
    1. public class NetworkVariablesManager : NetworkBehaviour
    2. {
    3.     public NetworkVariable<PlayersConnected> playersConnected = new NetworkVariable<PlayersConnected>();
    4.     // Start is called before the first frame update
    5.     void Start()
    6.     {
    7.         playersConnected.OnValueChanged += OnSomeValueChanged;
    8.         if(NetworkManager.Singleton.IsServer){
    9.             playersConnected.Value = new PlayersConnected(){
    10.                 playerArray = new PlayerDetails[4]
    11.             };
    12.         }
    13.         SeeInitialValue();
    14.     }
    15.  
    16.     public void AddPlayer(PlayerDetails details, ulong clientId){
    17.         Debug.Log($"Added Player {details.name} for id {clientId}");
    18.         playersConnected.Value.playerArray[clientId % 4] = details;
    19.     }
    20.     private void SeeInitialValue()
    21.     {
    22.         if (playersConnected.Value.playerArray != null)
    23.         {
    24.             for (int n = 0; n < playersConnected.Value.playerArray.Length; ++n)
    25.             {
    26.  
    27.                 Debug.Log(playersConnected.Value.playerArray[n].name ?? "Empty");
    28.  
    29.             }
    30.         }
    31.  
    32.     }
    33.  
    34.     private void OnSomeValueChanged(PlayersConnected previous, PlayersConnected current)
    35.     {
    36.         Debug.Log($"Detected NetworkVariable Change: Previous: {previous} | Current: {current}");
    37.         if (playersConnected.Value.playerArray != null)
    38.         {
    39.             for (int n = 0; n < playersConnected.Value.playerArray.Length; ++n)
    40.             {
    41.                 Debug.Log(playersConnected.Value.playerArray[n].name ?? "Empty");
    42.             }
    43.         }
    44.  
    45.     }
    46.  
    47.     /*... somewhere else in my RPC code
    48.  
    49.     [ServerRpc]
    50.     void onJoinServerRpc(PlayerDetails player, ulong sourceNetworkObjectId)
    51.     {
    52.         if (IsServer)
    53.         {
    54.             Debug.Log($"Server Received the RPC #{player.name} on NetworkObject #{sourceNetworkObjectId}");
    55.             ServerManager.Instance.addPlayer(player, sourceNetworkObjectId);
    56.             netVarManager.AddPlayer(player, sourceNetworkObjectId);
    57.         }
    58.     }
    59. */
    60. }
    The code below is given by the examples, so Im just copying, but I'm not sure if it is necessary for string type. But am trying to see if it works
    Code (CSharp):
    1. // The class name doesn't matter here.
    2. public static class SerializationExtensions
    3. {
    4.     public static void SerializeValue<TReaderWriter>(this BufferSerializer<TReaderWriter> serializer, ref Url url) where TReaderWriter: IReaderWriter
    5.     {
    6.         if (serializer.IsReader)
    7.         {
    8.             url = new Url();
    9.         }
    10.         serializer.SerializeValue(ref url.Value);
    11.     }
    12. }
    Edit: It kind of works for 1 step. So the issue was, because custom struct is all null until a variable is passed in, and even so every object needs to start off as null, so when I serialize and deserialize, there causes some error. I have to work put null checks here and there when serializing, and deserializing for it to work. Now my writer is working but my reader has issue
     
    Last edited: Jun 10, 2023