#Blittable component type contains pointer field error

1 messages · Page 1 of 1 (latest)

placid torrent
#

I have this error coming from my authoring script:

Blittable component type contains a (potentially nested) pointer field. Serializing bare pointers will likely lead to runtime errors. Remove this field and consider serializing the data it points to another way such as by using a BlobAssetReference or a [Serializable] ISharedComponent. If for whatever reason the pointer field should in fact be serialized, add the [ChunkSerializable] attribute to your type to bypass this error.

Bit confused by this, it seems to relate to this component:

    public struct Walls : IComponentData
    {
        public SparseGrid WallGrid;
        public NativeHashMap<int, int> ConnectionFlags;
    }

It seems to specifically not like: public NativeHashMap<int, int> ConnectionFlags;

But I don't understand why, because its perfectly fine with SparseGrid of which contains:

public struct SparseGrid
{
    public readonly float GridSize;
    public NativeHashMap<int, NativeList<Entity>> Map;

    //ctor etc...
}```

My authoring code looks like this:

```csharp
var e = CreateAdditionalEntity(TransformUsageFlags.None);

NativeHashMap<int, int> Conns = new(0, Allocator.Persistent);
//for some reason can't use enum type so cast to int
for (int i = 0; i < a._wallTypes.Length; i++)
    Conns.Add((int)a._wallTypes[i], (int)a._connectFlags[i]);

AddComponent<Walls>(e, new()
{
    WallGrid = new(gridSize),
    ConnectionFlags = Conns
});

How do i correctly set this up?

fair path
#

You can’t bake native containers. What you’re doing is incorrect. The only “collection-like” things you can bake is blob array or dynamic buffer

placid torrent
#

oh, hmm so how do i get native containers to be involved for lookups ? dynamic buffer wont make much sense for sparse grid or my connection flag check

placid torrent
#

can i create them in a system in the on create call instead?

fair path
placid torrent
#

well i could create more basic entities then use a system to create the native containers perhaps

fair path
#

At runtime it all can be remapped to native containters

#

Or recreated directly at runtime

placid torrent
#

i see, that said, why does it allow sparse grid to be created ?

#

if i comment out the connection flag hash map it is perfectly happy with my sparse grid. very odd

fair path
#

Your SparseGrid even more incorrect, you can’t have nested native containers. Only unsafe collections can be nested inside native collections.

placid torrent
#

why does it not give compile warnings then ?

#

strange

fair path
#

And again you physically can’t bake ANY native container in baker, memory they allocate not serialised anywhere.

placid torrent
#

okay, so i have to use UnsafeList<T> for the value of my hashmap ?

fair path
#

Yes if you need, but again - not baker compatible, only for runtime. And don’t forget about value type nature of unsafe containers and how easy you can fall in to length and actual data size mismatch if you not careful enough with passing it around by value.

placid torrent
#

yeah ill create them in a system's on create function, as for size/length not sure what you mean yet. ill cross that bridge when i get to it i guess.

#

ah it makes sense now that i have to make containers in systems since they need to be disposed too

misty solar
lavish glen
#

This is the data layout of UnsafeList. Except the field at line 66, everything else is not a pointer but pure value.

#

Supposedly you have a code like this:

public struct UnsafeListComponent : IComponentData
{
    public UnsafeList<int> list;
}
#

When you retrieve the list from inside that component, what you have is an independent copy, not anymore related to what is stored inside that component.

#

So if the list stored inside the component changed (its Length changed, for example), that change will never reflect upon your copies.

#

That's why NativeList is implemented as a wrapper around the pointer to an UnsafeList.

#

NativeList is also a value type. But because it contains only 1 pointer, it can act like a reference type.

#
var x = new NativeList<int>(...);
var y = x;
var z = y;
#

Each of these is indeed an independent copy. But inside them is the same pointer that points to the same memory block.