Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Component arrays

Discussion in 'Project Tiny' started by sniffle63, Jun 13, 2019.

  1. sniffle63

    sniffle63

    Joined:
    Aug 31, 2013
    Posts:
    353
    brave_2019-06-13_02-22-50.png In the TypeScript version we could make arrays on our components within the editor, but it seems to give errors and close out of the project if i try to add an array to a component, curious if im doing it wrong or if its not currently supported.
    rider64_2019-06-13_00-34-19.png

    After doing some reading, iv learned 1 deminsional arrays of blittable types should still be blittable, but im not able to use just a
    Code (CSharp):
    1. int[] counter
    which if im not mistaking, should be a 1 dimensional array of a blittable type brave_2019-06-13_02-22-50.png

    I thought if i used [HideFromInspector] it would work. Do to whats stopping it, is just a serilization check, but i still get the same error
     
    Last edited: Jun 13, 2019
  2. Ferran_SP

    Ferran_SP

    Joined:
    Jul 9, 2018
    Posts:
    27
    The key is that this 1-dimensional array you're using is not of fixed length, thus it's not blittable.
    If you tried with
    public int[10] counter

    it would work, because it's a fixed-size array (but this probably is not what you want to use).
    But you have a type (the Snake struct) that contains a variable array (int[]) of a blittable type (int), and this is by definition not-blittable.
     
  3. elcionap

    elcionap

    Joined:
    Jan 11, 2016
    Posts:
    138
    As @Ferran_SP pointed a struct with array inside it's not blittable.
    For array/list you should use DynamicBuffer:

    Code (CSharp):
    1. public struct Snake : IBufferElementData {
    2.     public Entity Segment;
    3. }
    4.  
    5. class FooSystem : ComponentSystem {
    6.     protected override void OnUpdate() {
    7.         Entities
    8.             .ForEach((DynamicBuffer<Snake>  snakes) => {
    9.                 snakes.Add(new Snake {
    10.                     Segment = SomeEntity
    11.                 });
    12.             });
    13.     }
    14. }
    You can read more here https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/dynamic_buffers.html

    Just pay attention that components declared inside the ForEach must follow an order and DynamicBuffer must be declared without ref and before ComponentData.

    Code (CSharp):
    1. Entities
    2.     .ForEach((DynamicBuffer<SomeBufferElementData> foo, ref Translation translation) => {
    3.         //
    4.     });
    []'s
     
  4. sniffle63

    sniffle63

    Joined:
    Aug 31, 2013
    Posts:
    353
    Ohh cool, so if i understand correctly id do something along the lines of this..

    Code (CSharp):
    1. public struct Segment: IBufferElementData {
    2.     public Entity Reference;
    3. }

    Code (CSharp):
    1. entityManager.AddBuffer<Segment>(snakeEntity);

    Code (CSharp):
    1. class FoodSystem : ComponentSystem {
    2.     protected override void OnUpdate() {
    3.         Entities
    4.             .ForEach((DynamicBuffer<Segment>  segments) => {
    5.                 segments.Add(new Segment{
    6.                     Reference = SomeEntity
    7.                 });
    8.             });
    9.     }
    10. }

    Then after i add the buffer id use it as you stated before.

    I dont currently have unity open, so ill ask here, can the DynamicBuffer be added as a variable inside of the IComponentData after the IBufferElementData is created
     
  5. elcionap

    elcionap

    Joined:
    Jan 11, 2016
    Posts:
    138
    Exactly.
    You can also set the data after adding:

    Code (CSharp):
    1. var segments = EntityManager.AddBuffer<Segment>(entity);
    2.  
    3. segments.Add(...);
    But be aware that an structural change will invalidate the buffer:

    Code (CSharp):
    1. var buffer1 = EntityManager.AddBuffer<Element1>(entity);
    2. var buffer2 = EntityManager.AddBuffer<Element2>(entity);
    3.  
    4. buffer1.Add(...); // INVALID
    5. buffer2.Add(...); // VALID
    In this case you will need to get the a new reference to the buffer after the structural change:

    Code (CSharp):
    1. EntityManager.AddBuffer<Element1>(entity);
    2.  
    3. var buffer2 = EntityManager.AddBuffer<Element2>(entity);
    4. var buffer1 = EntityManager.GetBuffer<Element1>(entity);
    5.  
    6. buffer1.Add(...); // VALID
    7. buffer2.Add(...); // VALID
    It's the same for adding/removing components.
    There is also a trick (explained in the docs link) about the buffer capacity and the relation with the chunk and heap.

    Nop, DynamicBuffer aren't valid to be stored in components. The same with any other NativeContainer (NativeArray, NativeList, etc).

    []'s
     
  6. sniffle63

    sniffle63

    Joined:
    Aug 31, 2013
    Posts:
    353
    Excellent! Thanks a ton
     
  7. Dunk86

    Dunk86

    Joined:
    May 10, 2015
    Posts:
    53
    From what I'm reading, it seems like these DynamicBuffers are alternatives to IComponentDatas? As in, they attach to Entities, and store some data? Then you access them in a similar way (get/set buffer vs get/set component on an Entity)?
    Can you store a reference to a DynamicBuffer from a Component?
    I haven't played with Tiny Buffers yet, but it seems they are useful for dynamic data only, since they won't appear in the inspector correct?

    Argh too many questions. These answers shouldn't be in a thread, Buffers should be added to the documention: https://docs.unity3d.com/Packages/com.unity.tiny@0.15/manual/scripting.html
    :D
     
    Last edited: Jun 14, 2019
  8. Zionisias

    Zionisias

    Joined:
    Apr 23, 2019
    Posts:
    40
    I believe Unity Tiny is planning to complete the documentation for the current functionalities by the next update they will release. There was a mention of this under the original C# post under Documentation, but it was a bit unclear what exactly was meant.
     
    Dunk86 likes this.
  9. elcionap

    elcionap

    Joined:
    Jan 11, 2016
    Posts:
    138
    Yep, they are alike the IComponentData. In ECS there is, currently, four types of ComponentTypes.
    IComponentData: Mostly common case.
    IBufferElementData: Used to store non fixed data.
    ISharedComponentData: Used to group data.
    UnityEngine.Component: Mostly used in hybrid integration (not support in Tiny AFAIK).
    There is a variant to the first three called ISystemStateComponentData, ISystemStateBufferElementData and ISystemStateSharedComponentData what operate the same way that the non SystemState versions but are used in ReactiveSystems.

    Nop. IComponentData don't accept any reference.

    I'm not used to the Tiny environment. Tiny use the same base as Unity ECS that I'm familiar with. Considering that people in Tiny are fresh about a lot of what was already discussed in the DOTS forum, I'm just trying to help with some basic questions.

    From documentation perspective, keep in the Tiny docs it's a good start. But a lot of the features of Tiny are shared to Unity ECS. The same with a lot of solutions. Maybe keep an eye in the DOTS forum can help a bit with some specification.

    []'s
     
    sniffle63 and raymondyunity like this.
  10. Mijawel

    Mijawel

    Joined:
    Dec 11, 2018
    Posts:
    2
    I want to have a simple array of float3 inside a component. My understanding is that I can't do that and must use a Dynamic Buffer instead and add that to the entity.

    I have looked through the documentation for Dynamic Buffers but I can't work out how to use it as an array of type Float3 and adding and removing elements by index.

    Would anyone be able to provide a small example of how to do that please?

    (This is what I have done so far, but probably wrong)

    Code (CSharp):
    1. [InternalBufferCapacity(100)]
    2.     public struct PathArray : IBufferElementData
    3.     {
    4.         // These implicit conversions are optional, but can help reduce typing.
    5.         public static implicit operator float3(PathArray e) { return e.Value; }
    6.         public static implicit operator PathArray(float3 e) { return new PathArray { Value = e }; }
    7.  
    8.         // Actual value each buffer element will store.
    9.         public float3 Value;
    10.  
    11.     }
    Code (CSharp):
    1. DynamicBuffer<PathArray> pathArray = EntityManager.GetBuffer<PathArray>(entity);
    2.                         pathArray.Add(value);
    3.                         //but don't know how to pull something off the buffer