Search Unity

Resolved Netcode INetworkSerializable for Dictionarys

Discussion in 'Netcode for GameObjects' started by Finn_O, Mar 3, 2022.

  1. Finn_O

    Finn_O

    Joined:
    Nov 18, 2020
    Posts:
    11
    I am trying to Use a Dictionary in a Rpc with Netcode.
    Code (CSharp):
    1. public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    2.         {
    3.             serializer.SerializeValue(ref exampleDictionary);
    4.         }
    But it says that it cant serialize it ("The type 'Dictionary<string, IMovementInfoItem>' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'BufferSerializer<T>.SerializeValue<T>(ref T)'")

    After that I tried to Wrap the Dictionary and implement the INetworkSerializable Interface, baut I failed since it uses the same Method for Serialization and Deserialization. Than I found the possibility to add WriteValueSafe() and ReadValueSafe() but it doesnt work for Generic Types (I think). I Found them here https://docs-multiplayer.unity3d.com/docs/advanced-topics/custom-serialization.

    Can somebody point me in the right direction or tell me what Im doing wrong?
     
  2. Finn_O

    Finn_O

    Joined:
    Nov 18, 2020
    Posts:
    11
    Update:
    I tried turning the dictionary into an Array of KeyValuePairs but these arent serializable either.
    Code (CSharp):
    1. internal struct NetworkDictionaryKeyValuePair<TKey, TValue> : INetworkSerializable where TKey : struct where TValue : struct
    2.     {
    3.         public TKey Key;
    4.         public TValue Value;
    5.  
    6.         public NetworkDictionaryKeyValuePair(TKey key, TValue value)
    7.         {
    8.             Key = key;
    9.             Value = value;
    10.         }
    11.  
    12.         public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    13.         {
    14.             serializer.SerializeValue(ref Key);
    15.             serializer.SerializeValue(ref Value);
    16.         }
    17.     }
    The Error is the same because the types of Key and Value are supposed to be non-nullable. But as far as I know they are Non-Nullable because they can only be stuct types.
     
  3. Finn_O

    Finn_O

    Joined:
    Nov 18, 2020
    Posts:
    11
    Update:
    I Solved it for me by turrning the Dictionary to a JSON and than use the NetworkSerializer on the string. Its not elegant but it works for now.
    Code (CSharp):
    1. public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    2.         {
    3.             string dictionaryJSON = "";
    4.  
    5.             if (serializer.IsWriter)
    6.             {
    7.                 dictionaryJSON = JsonUtility.ToJson(exampleDictionary );
    8.             }
    9.             serializer.SerializeValue(ref dictionaryJSON );
    10.             if (serializer.IsReader)
    11.             {
    12.                 exampleDictionary = JsonUtility.FromJson<Dictionary<string, Item>>(dictJSON);
    13.             }
    14.         }
    Edit:
    I changed the Json Serializer to Newtonsofts JSON.NET since Unitys cant handle Dictionarys.

    But my Solution cant be optimal. Can anyone help me by giving an example of a better solution?
     
    Last edited: Mar 10, 2022
    madalinadaniel60 likes this.
  4. CaptainCrouton89

    CaptainCrouton89

    Joined:
    Apr 18, 2019
    Posts:
    2
    You can convert the keys and values into two arrays, and then send them over together. They'll maintain their order, and you can zip them back up once they are received. There may be some other methods as well, but this is probably the simplest.
     
  5. Finn_O

    Finn_O

    Joined:
    Nov 18, 2020
    Posts:
    11
    Thanks I'll change to that. The JSON serielization took up a lot of computing time.