Search Unity

Should I be adding new components or have an "Empty" state of the component (Archetypes)?

Discussion in 'Entity Component System' started by frankfringe, Feb 9, 2019.

  1. frankfringe

    frankfringe

    Joined:
    Feb 9, 2019
    Posts:
    105
    Hi,

    so I am writing a simulation-like RTS game. The humans in the game have a "Goal" most of the time (walk to the mine, walk to home etc.). At first I thought that I would just have a system that searches for humas without a Goal and if so add a Goal component. I have two questions.

    1. How do I do that? This code filters out all the Entities I need
    Code (CSharp):
    1.     [RequireComponentTag(typeof(Human))]
    2.     [RequireSubtractiveComponent(typeof(Goal))]
    3.     [BurstCompile]
    4.     struct FindGoalJob : IJobProcessComponentData<>
    5.  
    But how do I then add a component in the execute method?

    2. Is that the right way to do it? As I understand it with the archetypes, this would result in Entities being copied around between chunks all the time as I add Goals and then remove goals when they are finished and add goals again. Should I instead have an "Empty" state (say goal_id = 0) on my Goal component or something like that?

    Thanks
     
  2. BrendonSmuts

    BrendonSmuts

    Joined:
    Jun 12, 2017
    Posts:
    86
    1) You can use the IJobProcessComponentDataWithEntity interface instead, pass an EntityCommandBuffer to your job use EntityCommandBuffer.AddComponent(entity, new Gloal()) to add the component to that entity once the buffer is played back.

    2) "Is this the correct way" questions are pretty hard to answer in the ECS world as there are many access pattern/usage considerations you need to bear in mind to give the best answer. I would say if you are potentially adding/removing thousands of goal components every frame then the entity copies would probably become something you should consider. My guess is that it's more likely that entity goals are going to persist a fair amount of time and so this tagging approach should work out just fine for you.
     
  3. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    Remember that if you use EntityCommandBuffer in the job you can't use burst compile.
     
  4. frankfringe

    frankfringe

    Joined:
    Feb 9, 2019
    Posts:
    105
    Thanks for the fast and good replies. Is this ( https://gist.githubusercontent.com/...4da42431c85e56f7f1eae1e1/EnemyHealthSystem.cs ) as done here ( https://medium.com/@gamevanilla/survival-shooter-using-unitys-entity-component-system-revisited-874cd69085ae ) still the correct way to implement an
    EntityCommandBuffer
    (using an EndFrameBarrier?)

    I am asking since there are surpressed warnings in the code. I did not find any better tutorial on how to use
    EntityCommandBuffer
    .

    I also have one more question. In the case I described above (adding new goals to some robots), which really does not happen to often (maybe once every few frames) should I still use a jobbified system or should I just use a normal system and the EntityManager instead maybe? Does using a Jobbified system have any drawbacks?
     
  5. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    I think so. You can either inject EndFrameBarrier or inject your own barrier depending on the order you want for "things" to be playback.
    Here you can find a good post about how there order of barriers happen.

    Still, i would use the "Goal" component in all required entities and change the "goal_id" using burst jobs.
     
  6. frankfringe

    frankfringe

    Joined:
    Feb 9, 2019
    Posts:
    105
    Thanks For the link.
    Should I then just run through all humans in every frame and check for
    goal_id = 0
    ?
     
  7. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    I would do that.
    Don't know what are you going to there, but if you do it in IJobProcessData with burst it's extremely fast.