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

Grab a Component by Type within a Job

Discussion in 'Entity Component System' started by TheGabelle, May 21, 2020.

  1. TheGabelle

    TheGabelle

    Joined:
    Aug 23, 2013
    Posts:
    242
    I'm trying to build a Stat - Affect system. My first attempt was a unique system, component, and affect buffer for each stat, but it smelled like a bad design. So, I thought maybe I could use a single dynamic buffer of affects where each affect holds a reference to whichever stat component it should modify. I'm unsure if there's a proper way to do something akin to the code below, or if it's a bad idea:
    Code (CSharp):
    1. public struct Health : IComponentData
    2. {
    3.     public int Value;
    4.     public int MaxValue;
    5. }
    6.  
    7. // unknown number of other stats with same fields
    8.  
    9. public struct StatAffect : IBufferElementData
    10. {
    11.     public Type TargetComponent;
    12.     public int Value;
    13.     public int Iterations;
    14.     public float Delay;
    15.     public float Time;
    16. }
    17.  
    18. public class StatAffectSystem : SystemBase
    19. {
    20.     protected override void OnUpdate ()
    21.     {
    22.         // [NativeDisableParallelForRestriction]  
    23.         Entities.ForEach( (Entity entity, DynamicBuffer<StatAffect> statAffectBuffer) => {
    24.            
    25.             foreach (var statAffect in statAffectBuffer)
    26.             {
    27.                 // get some Entity component using statAffect.TargetComponent
    28.                 // logic to modify component
    29.                 // write to component with updated values
    30.             }
    31.         })
    32.         .ScheduleParallel();
    33.     }
    34. }
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,993
    You would have to hardcode an enum for each component type to get this to work. Separate jobs seems like a better solution.
     
  3. TheGabelle

    TheGabelle

    Joined:
    Aug 23, 2013
    Posts:
    242
    What I dislike about separate jobs is each one would have the same logic, the only difference being a component and buffer type. Could I build a single job with a generics that I could reuse? This may have been covered in another forum thread, but the search feature isn't working today.
     
  4. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,993
    Can you show code of what this looks like with two jobs and two types?
     
  5. swejk

    swejk

    Joined:
    Dec 22, 2013
    Posts:
    20
    This does not answer your question, but maybe it will help you to accomplish your goal.
    In my stat system, I dont have separate component type for each stat. I only have buffer with stats, each stat having its exclusive index, ie. Health has index 3 in stat buffer. When applying effect i dont have to switch stat type, i just directly access it by index.
    This have its own flaws, like each entity with stats has the buffer element for each possible stat which can be wastefull. Also the stat value scale (int vs. floats) must be same for each stat.