Unity-Technologies / com.unity.netcode.gameobjects

Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.
MIT License
2.15k stars 435 forks source link

INetworkSerialization issues with NativeArrays and NativeLists. #3071

Open MilkyChestnut opened 2 months ago

MilkyChestnut commented 2 months ago

Description

NativeArrays seem to throw a memory leak error if I attempt to serialize the class using them with INetworkSerializable. NetworkSerialize with a NativeArray and setting the Allacator.Persistent will throw this memory leak issue.

` public class TestActionSystem : INetworkSerializable, IDisposable {

    private NativeArray<int> _intArray;

    public void Setup()
    {
        _intArray = new NativeArray<int>(1, Allocator.Persistent);
    }

    public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    {

        serializer.SerializeValue(ref _intArray, Allocator.Persistent); //this will throw the error
    }

    public void Dispose()
    {
        Debug.Log($"Disposing _intArray {_intArray.IsCreated} {_intArray.Length}");
        if (_intArray.IsCreated)
        {
            _intArray.Dispose();
        }

    }
}

` NativeArrays with a custom struct also break if that custom struct impliments INetworkSerializable. If i dont add that interface and or serialize using the methods here it does work.

NativeLists dont even appear to work. I tried the simplest version with just ints, and this didn't work . ` public class TestActionSystem : INetworkSerializable, IDisposable {

    public NativeList<int> IntList => _intList;

    private NativeList<int> _intList;

    public void Setup()
    {
        _intList = new NativeList<int>(0, Allocator.Persistent);
    }

    public void Add(int value)
    {
        _intList.Add(value);
    }

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

    public void Dispose()
    {
        if (_intList.IsCreated)
        {
            _intList.Dispose();
        }
    }
}

`

My goal is hopefully just use a NativeList with my own custom structs with a few more NativeLists inside (to get around the issue of directly nesting NativeLists with other NativeLists.

But I can't even get the NativeArrays to work without a memory leak, and the NativeLists to even serialize.

Reproduce Steps

Provided in description

Actual Outcome

NativeArray with a int fires a memory leak exception. (needs to work with custom structs)

NativeList with a int won't even serailize.

Expected Outcome

NativeArray doesn't fire memory leak

NativeList serailizes on the network.

Screenshots

If applicable, add screenshots to help explain your problem.

Environment

Additional Context

Add any other context about the problem here. Logs, code snippets would be useful here but please also consider attaching a minimal Unity project that reproduces the issue.

MilkyChestnut commented 2 months ago

Further follow up, conversion methods for NativeList don't seem to work either. I get an error about things not being implimented.

_intArray = _nativeIntList.ToArray();

NoelStephensUnity commented 1 month ago

@MilkyChestnut If you could provide me with the scripts you are using for both the INetworkSerializable implementations and the scripts that use them it would be very helpful. As an example, I am not sure if you are using TestActionSystem in an RPC or as the type within a NetworkVariable. Knowing the context of usage will help me to narrow down this issue so I can replicate it on my side.

MilkyChestnut commented 1 month ago

@NoelStephensUnity Sure just give me some time to setup a demo. I've resorted to using work arounds fn with just regular arrays and lists that I serialized into arrays. I'm crunching rn so give me time to finish and Ill wip up a demo project for you.

And TestActionSystem is passed via a RPC