Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

UTiny and ECS

Discussion in 'Entity Component System' started by dzamani, Dec 9, 2018.

  1. dzamani

    dzamani

    Joined:
    Feb 25, 2014
    Posts:
    122
    Hi,

    There is something that I don't get and I was hoping someone from this team or the UTiny one could answer (I've created my post here because the question is a bit more related to ECS I think ?).
    So, we have the concept of a Component on an Entity and that component should only be considered as a data container, an entity can only have one component of a specific type. Until that point everything is okay.

    I will give a use case for my question:
    - We have HealthComponent with the current health of a character entity
    - We want to apply Damage from multiple sources so we create a DamageEvent (which is also a IComponentData which will be consumed by a system).

    How do we apply multiple DamageEvents to the same HealthComponent without losing performance (IMO creating / populating a list of DamageEvents per HealthState during the update of the DamageSystem isn't a good solution).

    Then there is UTiny allowing you to create component from the editor but with arrays and references to other components ? At this point, correct me if I'm wrong, there is no elegant way to do that with ECS, you will only lose performances inside a job since you are trying to iterate overt IComponentData with referenced fields (it will also throw warnings / errors in some cases since it's written that we should not do that).

    A "good" solution would be to store a list of DamageEvents on the HealthComponent and use that or have a weak reference to HealthComponent on the DamageEvent and be able to dereference it while we are in a job.

    I know there is several solutions:
    - Buffer arrays but the way I see it, it was introduced in this way: "we've added this feature to help people who can't get used to ECS principles" so I'm often tempted to use it but I haven't succumbed yet (again just my opinion)
    - Entity field that's used to get the corresponding component before sending it to a job
    - SharedComponent with filters also before a job
    - Keep a list for each component (dictionary with Entity as a key) in the system and fetch the corresponding list just before scheduling the job (and I feel like it's a very good solution, sometimes not creating Entity could give you a performance boost based on your use case)

    I may have missed it but I have not seen anyone saying that one of these solutions is the best followed with proofs (performance and ECS philosophy wise).
    So is the way UTiny is now a choice because it's not using jobs (since there is no multithreading yet with web platforms and Unity) or is there some magic done or one of the above solutions was picked as the best choice ?

    I feel like any issue could be solved with ECS but not all of these solutions will be able to be jobified.

    Feel free to correct any of the facts I've just said and also if it's more a UTiny question, then could this post be moved over their forum ?

    Thanks!
     
    guizmoquutamo likes this.
  2. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Dynamic Buffer perfectly results in ECS-style data structure if your elements stays under the initial capacity. "ECS principles" you are referring to seems to be that one chunk must be concretely laid out making all memory position inside it predictable. If going over capacity, then yes it is a bit out of ECS?

    For an another "multiple" problem you could look at Unity's own Attach strategy. It is used to attach a child Entity with Parent entity. One parent obviously can hold many children, but you cannot just attach multiple children component. What it did is to create a new entity describing the pair, then there is a system which consume and destroy it on update. The consumation result goes in separately stored NativeMultiHashMap, where one parent key will maps to multiple children. Is that cheating ECS? Kinda, but I could also think that NativeMultiHashMap (and other Native containers) which obviously put the data out of ECS database are still part of ECS tools.
     
  3. dzamani

    dzamani

    Joined:
    Feb 25, 2014
    Posts:
    122
    Dynamic buffer would be used with a specific capacity so that would not be an issue. It's like it's not described as the perfect way of working with ECS, imagine trying to convert OOP code to ECS and mass using dynamic buffers, do you think that the result would be something respecting ECS principles ?

    Now the Attach system is something that I already read about and that's the 4th solution from my previous post, it has however, a few issues:
    - The UpdateAttach method is ran on System Update and not from a job (proving my point that sometimes you can not use jobs)
    - DamageEvent, like I said, is consumed just like Attach component but there is a huge difference, for the DamageEvent we need to change HealthComponent which give us 2 options: either we use a system with a queue or list of DamageEvents and the jobs would run on HealthComponent (basically making DamageEvent not an IComponentData) or we do the opposite and store HealthComponents in a list on the system and each DamageEvent has an way to get it from that list (could use index or Dictionary with Entity as keys).