Search Unity

Setting a Dynamic Buffer's capacity when creating an Archetype

Discussion in 'Entity Component System' started by orionburcham, Dec 30, 2018.

  1. orionburcham

    orionburcham

    Joined:
    Jan 31, 2010
    Posts:
    488
    According to this whitepaper: https://github.com/Unity-Technologi...er/Documentation/reference/dynamic_buffers.md

    ...the intended way to set a dynamic buffer's capacity is with a
    [InternalBufferCapacity(/*size*/)]
    Attribute, which decorates an IBufferElementData.

    Is there also a way to set this buffer's size when manually creating an archetype (using EntityManager.CreateArchetype())?

    I understand Unity can't let each entity have a randomly different buffer size- that would destroy the chunk layout.

    But having different buffer sizes per archetype shouldn't fragment chunk layout.

    Right now, I'm looking at writing dozens of separate IBufferElementData types, with the exact same data, just so I can have archetypes with different buffer sizes:

    Code (CSharp):
    1. [InternalBufferCapacity(15)]
    2. public struct EnemyType01LootData : IBufferElementData
    3. {
    4.     LootType lootType;
    5.     int count;
    6. }
    7.  
    8. [InternalBufferCapacity(22)]
    9. public struct EnemyType02LootData : IBufferElementData
    10. {
    11.     LootType lootType;
    12.     int count;
    13. }
    14.  
    15. [InternalBufferCapacity(10)]
    16. public struct EnemyType03LootData : IBufferElementData
    17. {
    18.     LootType lootType;
    19.     int count;
    20. }
    21.  
    22. [InternalBufferCapacity(23)]
    23. public struct EnemyType04LootData : IBufferElementData
    24. {
    25.     LootType lootType;
    26.     int count;
    27. }
    28.  
    29. // ect...
    I imagine writing unique Components for each Enemy type is not something the ECS team would like to see. That's also going to affect System design.

    Is there a alternate API I don't know about? Thanks for any help. :)
     
    Last edited: Dec 30, 2018
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    This isn't really important. Just use 1 buffer and pick a capacity that makes the most sense in general and resize as you need.

    Your entities can have totally different buffer sizes. Buffer array is just a list and can be resized at will individually for each entity.

    This is the difference between the old fixed array system where the size has to be defined in the archetype.
     
    Jack-Mariani and orionburcham like this.
  3. orionburcham

    orionburcham

    Joined:
    Jan 31, 2010
    Posts:
    488
    Thanks for the info. A few questions, if you have time:

    1. How does one set a new capacity for an entity's buffer? What's the API? (Sorry to ask this - I just can't seem to find API documentation for dynamic buffers. Unity's ECS Sample git repo has a broken link in their documentation.)

    2. Can resizing create garbage? The documentation link in the OP mentions that they allocate on the heap if their capacity is exhausted.

    3. When you say the buffer array is just a list...Do you mean it's literally a List<T>?

    4. For clarification: Are entities with different buffer sizes (but identical in every other way) considered different archetypes?

    Thanks!
     
    Last edited: Dec 30, 2018
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    1. When you use Add() if you don't have capacity it'll resize (double I think). If you want to set a specific length, you can use I believe it's called ResizeUninitialized. Note as the name suggestions, this is Uninitialized so the values will be garbage. I also wrote an extension called ResizeInitialized if you want to memclear to defaults after you initialize. https://forum.unity.com/threads/a-collection-of-extensions-systems-etc.605116/

    2. No

    3. I mean it pretty much works the same as NativeList<T>

    4. No, same archetype.
     
  5. Spy-Shifty

    Spy-Shifty

    Joined:
    May 5, 2011
    Posts:
    546
    Code (CSharp):
    1. DynamicBuffer<Component1> myDynamicBuffer = ...;
    2. myDynamicBuffer.ResizeUninitialized(1024)
    No because it's native collection.

    It's a native collection... It can't be managed code at all otherwise it wouldn't be "jobifyable"

    No, they have the same archetype