How do I NetworkSerialize a List in INetworkSerializable?

I have a struct that has all the card data I want to serialize. The strings and ints work perfectly, but when I try to add a List of ints, the NetworkSerialize function says it cant convert from ref list to ref string

You cannot (directly) serialize a list. You can however serialize an array of strings, so if you add an intermediate ToArray step when writing (and transform back when reading) it should work.

I tried doing this but im getting errors that say my CardData struct and any levels of nesting in it must be a non-nullable type.

Can you post the relevant bits of your code?

Using the documentation for reference, this is what i came up with

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Netcode;
using System;
using Unity.Collections;

public struct CardData : INetworkSerializable, IEquatable<CardData>
{
   
    public int DamageAmount;
    public List<int> EffectIndex;

    public CardData(int damageAmount, List<int> effectIndex)
    {
        DamageAmount = damageAmount;
        EffectIndex = effectIndex;
    }

    public bool Equals(CardData other)
    {
        return DamageAmount == other.DamageAmount &&
                EffectIndex == other.EffectIndex;
    }

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

        int length = 0;
        int[] Array = EffectIndex.ToArray();
        if (!serializer.IsReader)
        {
            length = Array.Length;
        }

        serializer.SerializeValue(ref length);

        for (int n = 0; n < length; ++n)
        {
            serializer.SerializeValue(ref Array[n]);
        }
    }
}

This is in the right direction, but notice that line 31 fails when reading because EffectIndex will be empty. Also, you don’t convert back from Array to EffectIndex when reading so the array will never be filled.

I can’t test this right now (on my phone), but I suspect something like this should work:

        int length = 0;
        int[] Array;
        if (!serializer.IsReader)
        {
            Array = EffectIndex.ToArray();
            length = Array.Length;
        }
        serializer.SerializeValue(ref length);

        if (serializer.IsReader)
        {
            Array = new int[length];
       }
        for (int n = 0; n < length; ++n)
        {
            serializer.SerializeValue(ref Array[n]);
        }

        if (serializer.IsReader)
        {
            EffectIndex = Array.ToList();
       }

On your line 16, I get a "Use of unassigned local variable ‘Array’ " error. Below is my fix which I’m hoping is the right way. Although there are no more errors on my IDE, I still get the following error.
“The type ‘CardData’ 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 'NetworkVariable”

int length = 0;
        int[] Array;
        if (!serializer.IsReader)
        {
            Array = EffectIndex.ToArray();
            length = Array.Length;
        }
        else
        {
            Array = new int[length];
        }
        serializer.SerializeValue(ref length);

        for (int n = 0; n < length; ++n)
        {
            serializer.SerializeValue(ref Array[n]);
        }

        if (serializer.IsReader)
        {
            EffectIndex = Array.ToList();
        }

Goodmorning,
I have the same problem and I founded your solution but, when I try to change my data (from server to client) I recive the error “NullReferenceException: Object reference not set to an instance of an object”.
Can you help me with this problem?
Actually i’m using the following revision
Unity: 2022.3.5f1
UnityTransport:1.3.4
UnityNetcode for GameObjects 1.5.2

Thanks in advance

To those who stuck on here (like me before), here is the final workable code:

        int length = 0;
        int[] Array;
        if (serializer.IsWriter)
        {
            Array = EffectIndex.ToArray();
            length = Array.Length;
        }
        else
        {
            Array = new int[length];
        }
        serializer.SerializeValue(ref length);
        serializer.SerializeValue(ref Array);

        if (serializer.IsReader)
        {
            EffectIndex = Array.ToList();
        }
1 Like