Possible to use DynamicBuffer with [InternalBufferCapacity(0)] inside IComponentData?

Hi there,

I was wondering if there is a way to make a DynamicBuffer part of a component. Usually this should not work because the memory requirements are dynamic, however, for DynamicBuffers that have the [InternalBufferCapacity(0)] attribute, memory requirements for “inside the chunk”-memory should be known and constant. Hence, I was wondering if it was possible to put them inside a component. When I tried like this:

 [Serializable]
    [InternalBufferCapacity(0)]
    public struct Test1DB: IBufferElementData
    {
        public float3 Value;
    }

    [Serializable]
    [InternalBufferCapacity(0)]
    public struct Test2DB: IBufferElementData
    {
        public int3 Value;
    }

    public struct MyComponent: IComponentData
    {
        public DynamicBuffer<Test1DB> test1DB;
        public DynamicBuffer<Test2DB> test2DB;
    }

I get several problems. First of all, I couldn’t find a way to create a DynamicBuffer other than to attach one to an entity. So I attach it, then assign it to an instance of MyComponent, add that instance to the entity, and then I remove the (direct) DynamicBuffer component from the entity, hoping the buffer memory won’t get released (since there is a reference to it somewhere else (namely in the instance of MyComponent)). However, I still get a complaint:

MyComponent must be unmanaged (contain no managed types) and cannot itself be a native container type.

Is it just not possible (yet) or is there some workaround I haven’t found yet?

This is not how dynamic buffers work at all. The only way to create a dynamic buffer is through entity manager (either direct or deferred through entity command buffer). I suggest you brush up on them via the documentation.

https://docs.unity3d.com/Packages/com.unity.entities@0.16/manual/dynamic_buffers.html

1 Like

Thank you for confirming that the only way to create a DynamicBuffer is to attach one to an entity. While that can be inferred from the docs, I (still) couldn’t find it explicitly stated. And it is not the only point where the doc’s are lacking. For example (you mentioned ECB), under “Buffer reference invalidation”, they show an example of a buffer being invalidated. If they used an ECB in the example, would the buffer also be invalid after adding a second one?

Back to topic, in case someone stumbles upon this thread: The actual issue with storing the DynamicBuffer in a component is that if you remove the (directly attached) buffer from the entity, the external buffer memory will be freed, which obviously invalidates the buffer in the component. It makes sense but it also makes the whole concept of neatly grouping multiple buffers in one component moot, since they still have to be attached directly to the entity in order not to be freed. Bummer.

If by invalidating, you mean within a job, they are not invalidated with ECB in normal circumstances. But they can be invalidated with entity manager, if you do structural changes to entity.

Also, as discussed earlier, you can not have buffers within a component. Nesting of containers is not permitted. Just use entity archetype, or entity prefabs, to keep organised components and and buffers within.

Probably you could do something with pointers. But I doubt, this is worth hassle.

1 Like

This post might help.