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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Similar systems for entities with additional components

Discussion in 'Entity Component System' started by Wihtman, Aug 11, 2018.

  1. Wihtman

    Wihtman

    Joined:
    Aug 3, 2015
    Posts:
    10
    What would be the correct ECS approach to creating two systems that would have nearly identical components and functionality in OnUpdate?

    Say I have one system MySystem
    Code (CSharp):
    1. public class MySystem : ComponentSystem
    2. {
    3.     private struct Group group
    4.     {
    5.         public EntityArray Entity;
    6.         public ComponentDataArray<AddedFlagComponent> AddedFlag;
    7.         public ComponentArray<NiceComponent> Nice;
    8.         public readonly int Length;
    9.     }
    10.     [Inject] private Group m_group;
    11.  
    12.     protected override void OnUpdate
    13.     {
    14.         for( int i = 0; i < m_group.Length; i++ )
    15.         {
    16.             // Operate on group.Nice[ i ];
    17.  
    18.             PostUpdateCommands.RemoveComponent<AddedFlagComponent>( group.Entity[ i ] );
    19.         }
    20.     }
    21. }
    and another system AnotherSystem
    Code (CSharp):
    1. public class MySystem : ComponentSystem
    2. {
    3.     private struct Group group
    4.     {
    5.         public EntityArray Entity;
    6.         public ComponentDataArray<AddedFlagComponent> AddedFlag;
    7.         public ComponentArray<NiceComponent> Nice;
    8.         public ComponentArray<CoolComponent> Cool;
    9.         public readonly int Length;
    10.     }
    11.     [Inject] private Group m_group;
    12.  
    13.     protected override void OnUpdate
    14.     {
    15.         for( int i = 0; i < m_group.Length; i++ )
    16.         {
    17.             // Operate on group.Nice[ i ];
    18.             // Operate on group.Cool[ i ];
    19.  
    20.             PostUpdateCommands.RemoveComponent<AddedFlagComponent>( group.Entity[ i ] );
    21.         }
    22.     }
    23. }
    What is the appropriate way to make sure that I both MySystem and AnotherSystem don't each act on the entity? I also am imagining that I could separate the Cool operations into another system, but essentially I am using the AddedFlagComponent to work like an event - adding AddedFlagComponent from somewhere, then for the frame that AddedFlagComponent is on the entity, operate on Nice BUT if there is a CoolComponent then operate on Cool as well.

    Edit: Playing around more, it seems like having MySystem and the system that processes CoolComponent should be separate systems. No use trying to apply the concept of inheritance and overrides to systems when the operating on the extra component CoolComponent can just be handled in another system.
     
    Last edited: Aug 11, 2018
  2. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    Not sure if I understand your problem correctly but maybe use SubtractiveComponent<NiceComponent> on the second one so it acts only on Cool that is not Nice?
     
  3. Vacummus

    Vacummus

    Joined:
    Dec 18, 2013
    Posts:
    191
    From your code examples, it looks like you have 3 different behaviors:
    • operate on nice
    • operate on cool
    • remove AddedFlagComponent

    So I would break up each behavior into it's own System with the following injections:
    • OperateOnNiceSystem (AddedFlagComponent, NiceComponent)
    • OperateOnCoolSystem (AddedFlagComponent, CoolComponent)
    • RemoveAddedFlagComponent (AddedFlagComponent, Entity)
    That makes it more decoupled thus more flexible and scalable.
     
  4. Vacummus

    Vacummus

    Joined:
    Dec 18, 2013
    Posts:
    191
    ^ I did forget to note that you should also configure the OperateOnNiceSystem and OperateOnCoolSystem to run before the RemoveAddedFlagComponent system.
     
  5. Wihtman

    Wihtman

    Joined:
    Aug 3, 2015
    Posts:
    10
    Yep, breaking everything up into its own system is the way to go, for sure. I hadn't considered configuring having the two systems run before RemoveAddedFlag system, but that seems very appropriate for the situation. Thanks for the replies.