Struct contains a field of Unity.Collections.LowLevel.Unsafe.DisposeSentinel

Hi,

I have this IComponentData:

public struct DaytimeLight: IComponentData
    {
        public NativeArray<int> Timestamp;
        public NativeArray<float> Intensities;
    }

and this is the part of the proxy script where I initialize the values:

 public class DaytimeLightProxy : MonoBehaviour, IConvertGameObjectToEntity
    {
        [SerializeField] private Light light;
        [SerializeField] private DaytimeLightSnapshot[] snapshots;

        public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
        {
            NativeArray<int> timestamps = new NativeArray<int>(snapshots.Length, Allocator.Temp);
            NativeArray<float> intensities = new NativeArray<float>(snapshots.Length, Allocator.Temp);
           
            for (int i = 0; i < snapshots.Length; i++)
            {
                timestamps[i] = snapshots[i].Timestamp;
                intensities[i] = snapshots[i].Intensity;
            }
           
            var lightData = new DaytimeLight
            {
                Timestamps = timestamps,
                Intensities = intensities
            };

            dstManager.SetName(entity,"DaytimeLight");
            dstManager.AddComponentData(entity, lightData);
            dstManager.AddComponentObject(entity, light);

        }

And the error I get:

ArgumentException: DaytimeSystems.DaytimeLight contains a field of Unity.Collections.LowLevel.Unsafe.DisposeSentinel, which is neither primitive nor blittable.

Any idea of what I am doing wrong here?

You can’t use native containers in IComponentData.

You can use NativeSlice in IComponentData

Only cos it’s just wrapper and not “real” container itself. Native slice not allocate and not dispose anty thing, cos it’s only gets native array pointers. And you should manage all NA which from you gets NS for future dispose.

@alexandre-fiset I’d recommend using IBufferElementData:

public struct DaytimeLightSnapShot : IBufferElementData
{
    public int TimeStamp;
    public float Intensity;
}
1 Like

Ok thanks! I just thought that Unity were using these arrays so they would be compatibable with component data and jobs, but turns out it’s only for jobs.

Thank you very much for this. I’m now aware of dynamic buffers and that kind of explain why arrays wouldn’t work in IComponentData.

There are not so many articles / posts on the subject so it’s quite tough to even know how to write IBuggerElementData-based code efficiently. I guess it’s learning time :slight_smile:

1 Like

The official docs helped me get started :slight_smile:
https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/dynamic_buffers.html

The problem I see with dynamic buffers is that they are deprived of useful methods such as Find or Sort.

I wonder how someone would handle reordering an inventory based on the item name with this…

True. It ends up in about the same amount of CPU work being done, but more code to write.

It sort an array I would probably iterate through it, collect things in a native array and then overwrite the whole buffer with the result.

I am not at my computer but have you tried to interpret the buffer as a native array (.asArrray or so) and then sort this (i think there was a bubble sort somewhere in the ecs source) - this might work

Have not used ecs for a few months…so not sure if the above is all correct, still

@sngdan - That totally does work, I’ve done it before. Assuming you have write access to the buffer of course.