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.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

How to use Dots in right way to get best performance?

Discussion in 'Entity Component System' started by Michelle_Ca, Apr 27, 2020.

  1. Michelle_Ca

    Michelle_Ca

    Joined:
    Aug 19, 2019
    Posts:
    113
    Hi, I have started studying Data Oriented Technology Stack a while ago, and i really like this system where you can create very big games and more complex worlds faster, with a magic performance, especially for mobile and network games. now I am trying to find an alternative to everything with Dots.
    I was familiar with the traditional way of unity coding (MonoBehaviours , Scriptableobjects ).

    So I have some questions, I hope someone with experience can help me find the answers, because I am a little confused now :oops:

    1- in MonoBehaviour : when we have fixed var in a script, and they differ from GameObject to GameObject we were using Scriptableobject ,and we save that var in it and then we create like items or profiles that can be attached to the gameobject ,
    Q1- The question is do we use (blob asset) for the same purpose in Dots with Entities?

    Q2- Which way from these 3 ways of State Machine gives the best performance and why ?

    A : one JobComponentSystem and one IComponentData for all variables and state inside it
    Code (CSharp):
    1. protected override JobHandle OnUpdate(JobHandle inputDeps)
    2. {
    3.     JobHandle jobhandle = Entities.WithAll<PlayerTag>().ForEach((ref PlayerProfile pp) =>
    4.     {
    5.         switch (pp.state)
    6.         {
    7.  
    8.             case (idel):
    9.                  //donothing
    10.  
    11.             case (eating):
    12.                 //eat
    13.                 pp.food += 1;
    14.  
    15.             case (attacking):
    16.                 //attack
    17.                 pp.energy -= 1;
    18.  
    19.              case...etc
    20.         }
    21.     }).Schedule(inputDeps);
    22.     return jobhandle;
    23. }

    B- one JobComponentSystem and IComponentData for each Behavior (which I think it is the same)

    Code (CSharp):
    1. protected override JobHandle OnUpdate(JobHandle inputDeps)
    2. {
    3.     JobHandle jobhandle = Entities.WithAll<PlayerTag>().ForEach((ref StateProfile State, ref Food myfood,ref Energy myenergy,...etc) =>
    4.     {
    5.         switch (State.state)
    6.         {
    7.  
    8.             case (idel):
    9.             //donothing
    10.  
    11.             case (eating):
    12.                 //eat
    13.                 myfood.food += 1;
    14.  
    15.             case (attacking):
    16.                 //attack
    17.                 myenergy.energy -= 1;
    18.  
    19.             case ...etc
    20.         }
    21.     }).Schedule(inputDeps);
    22.     return jobhandle;
    23. }
    24.  
    C- JobComponentSystem and IComponentData for each Behavior and adding/removing Component states (which I think it is the best but i dont know)

    Code (CSharp):
    1.  
    2. protected override JobHandle OnUpdate(JobHandle inputDeps)
    3. {
    4.     JobHandle jobhandle = Entities.WithAll<IdelTag>().ForEach(( ) =>
    5.     {
    6.         //after an event
    7.  
    8.         remove IdelTag and add EatingTag
    9.  
    10.     }).Schedule(inputDeps);
    11.     return jobhandle;
    12. }
    13. protected override JobHandle OnUpdate(JobHandle inputDeps)
    14. {
    15.     JobHandle jobhandle = Entities.WithAll<EatingTag>().ForEach((ref Food myFood) =>
    16.     {
    17.  
    18.         myFood.food. += 1;
    19.         //after an event
    20.         remove EatingTag and add AttackingTag
    21.  
    22.     }).Schedule(inputDeps);
    23.     return jobhandle;
    24. }
    25. protected override JobHandle OnUpdate(JobHandle inputDeps)
    26. {
    27.     JobHandle jobhandle = Entities.WithAll<AttackingTag>().ForEach((ref Energy myEnergy) =>
    28.     {
    29.  
    30.  
    31.         myEnergy.energy -= 1;
    32.         //after an event
    33.         remove AttackingTag and add ...etc
    34.     }).Schedule(inputDeps);
    35.     return jobhandle;
    36. }
    37. ....etc
    Thanks in advance :) !!
     
    Krajca likes this.
  2. DreamersINC

    DreamersINC

    Joined:
    Mar 4, 2015
    Posts:
    130
    This might be a useful unite talks for you


     
    Michelle_Ca and Games4Stream like this.
  3. agurskis22cans

    agurskis22cans

    Joined:
    Jul 17, 2019
    Posts:
    9
    Components, components, components, which translates to data, data, data. Think of this as SQL database. You take one thing, you modify it, you save it back to the database.

    There is no such thing as a player. There is a Food component, Stamina component, Damage component.

    There is no such thing as an Attack Component. It's an action, and actions are systems, so it would be AttackSystem, which would use Damage Component and maybe Anger Component to cause damage to the Target Component.

    Forget OOP programming here. I know it's hard, it was the same for me when I started.

    The best analogy I can give you is as I said - SQL database. READ, MODIFY, SAVE.
     
    Michelle_Ca likes this.
  4. Michelle_Ca

    Michelle_Ca

    Joined:
    Aug 19, 2019
    Posts:
    113
    DreamersINC I will watch these videos thank you !!
     
  5. Michelle_Ca

    Michelle_Ca

    Joined:
    Aug 19, 2019
    Posts:
    113
    agurskis22cans thank you !
    What I am thinking about is simulation games where there is no input , But there are thousands of entities so each kind of entity should have a tag not (playertag) as i mentioned, that was just an example.
    So my question is, will (modifying alot of values inside the components in one system) be cheaper than (dividing the entities into groups by tags and processing them separately in couple of JobComponentSystems wich call just the needed components with adding and removing tags to move the entities from system to another) ?
     
    Last edited: Apr 29, 2020
  6. DreamersINC

    DreamersINC

    Joined:
    Mar 4, 2015
    Posts:
    130
    If I am understanding what you are asking correctly, from my understanding of DOTS each componentsystem and jobcomponentsystem should have one particular function. From my usage, modifying alot of values inside the components in one system requires having multiple jobs that do almost the same task just on the different set of entities.
     
    Michelle_Ca likes this.
  7. Michelle_Ca

    Michelle_Ca

    Joined:
    Aug 19, 2019
    Posts:
    113
    DreamersINC thanks !
    Actually, I am asking if we have (component A)&(component B)&(component C)(component enum state) attached to (20000 entities)
    and we have two options :

    1 - just one jobcomponentsystem processing all the components(a,b,c) for all the 20000 entities by an enum state, Which requires reference (ref) to all the components (a,b,c) for each entity being processed.

    2- three jobcomponentsystems each one of them process just one component (A) or (B) or (C) for just the entities who contains a tag like (AprocessTag) or(BprocessTag) instead of enum state, Which requires reference (ref) just to one component (A) or (B) or (C) for each entity being processed per jobcomponentsystem

    Which is better ?
    I hope that is clear:p
     
  8. Micz84

    Micz84

    Joined:
    Jul 21, 2012
    Posts:
    437
    You should avoid branching inside jobs. So if you can do not use ifs and switches. You can use tag components or ISharedComponentData and filtering.
    Unless you entities change state very often it should be more performer.
     
    Michelle_Ca likes this.
  9. DreamersINC

    DreamersINC

    Joined:
    Mar 4, 2015
    Posts:
    130
    Here is the questions you have to asked. Whats if an entity only have component A and B ? if you are using single system to update everything, you will have to write a system for each entity variation that can occur. Now you have multiple instance of the same system running with slight variations. It would be better than mono script but not the best you can get

    If component A,B, and C must be part of every entity, why are they separate components ?
     
    Michelle_Ca likes this.
  10. Michelle_Ca

    Michelle_Ca

    Joined:
    Aug 19, 2019
    Posts:
    113
    Micz84 thank you ! yes, actually the entities change state very often, do I have to stay away from tag components? and what is the alternative?
     
  11. Michelle_Ca

    Michelle_Ca

    Joined:
    Aug 19, 2019
    Posts:
    113
    DreamersINC yes they are part of every entity and they separate components
    Because we need to process them separately by several systems and for limit number of entities ,
    example if we made them one component: we have one job foreach (ref onecomponent) in this way we have made a reference for all the entities and their onecomponent every single update, although we wont process all the vars inside this onecomponent at the same time and for all the entities because we process them by the state of each entity so in this case there is a waste in resources, I think.
    but if we made them separate we can control which component we need for each Job and we can limit the number of entities inside each job by a Tagcomponent
     
    Last edited: Apr 30, 2020
  12. DreamersINC

    DreamersINC

    Joined:
    Mar 4, 2015
    Posts:
    130
    It sounds like you are doing something like my DOTS approach to Dave Mark's Infinite Axis Utility AI system. I have 3 types of components, Considerations, State, and ActionTag. Considerations are used to score the utility of each state. There are quite a few considerations, Health, Distance to target, Player Visibility etc etc.ActionTags tell what state to do. For systems, Each consideration get its out individual job to score. Each state has its own job to score itself. The only time would use a single job to score a state or consideration is if that used the same data.
    TBH the video of using EntityCommandBuffer look like frame work you should be interested in.
     
    Michelle_Ca likes this.
  13. Michelle_Ca

    Michelle_Ca

    Joined:
    Aug 19, 2019
    Posts:
    113
    Yes exactly! I will definitely use EntityCommandBuffer to modify the entities inside the JobComponentSystems without getting errors, What I also want is creating a game object for each entity because i'm going to use Animation Textures in GPU for render
     
  14. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    948
    Just watched the EntityCommandBuffer video. How do you perform immediate playback when using SystemBase.ScheduleParallel()? SystemBase does not have PostUpdateCommand.
     
  15. Micz84

    Micz84

    Joined:
    Jul 21, 2012
    Posts:
    437
    How often and how many entities change state? Changing state means your entities are moved around in memory. You would need to profile what is faster. I assume each entity does not change state every frame even every second. By using branching you pay cost of it every frame. I think it will be faster to use tag components or ISharedComponentsData. But as I said you would need to profile.
     
    Michelle_Ca likes this.