Netcode INetworkSerializable for Dictionarys

I am trying to Use a Dictionary in a Rpc with Netcode.

public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
        {
            serializer.SerializeValue(ref exampleDictionary);
        }

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.SerializeValue(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?

Update:
I tried turning the dictionary into an Array of KeyValuePairs but these arent serializable either.

internal struct NetworkDictionaryKeyValuePair<TKey, TValue> : INetworkSerializable where TKey : struct where TValue : struct
    {
        public TKey Key;
        public TValue Value;

        public NetworkDictionaryKeyValuePair(TKey key, TValue value)
        {
            Key = key;
            Value = value;
        }

        public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
        {
            serializer.SerializeValue(ref Key);
            serializer.SerializeValue(ref Value);
        }
    }

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.

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.

public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
        {
            string dictionaryJSON = "";

            if (serializer.IsWriter)
            {
                dictionaryJSON = JsonUtility.ToJson(exampleDictionary );
            }
            serializer.SerializeValue(ref dictionaryJSON );
            if (serializer.IsReader)
            {
                exampleDictionary = JsonUtility.FromJson<Dictionary<string, Item>>(dictJSON);
            }
        }

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?

1 Like

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.

Thanks I’ll change to that. The JSON serielization took up a lot of computing time.