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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Disable System temporary on single gameObject

Discussion in 'Entity Component System' started by DoYouRockBaby, Jul 26, 2018.

  1. DoYouRockBaby

    DoYouRockBaby

    Joined:
    May 21, 2018
    Posts:
    9
    Hello World,

    I'm currently trying to port my game to the ecs hybrid system.

    I started by splitting my different player movement into different System, for example Dash, Gravity, Jump, Movements.

    I think it's what ecs encourage me to do. Maybe i misunderstood the concept.

    The problem is the following, when i'm dashing, i want my Gravity and my Movement system to pause.

    I found those solutions in the forum :
    Code (CSharp):
    1.     public class ComponentSys : ComponentSystem
    2.     {
    3.         [Inject] private SomeSystem someSystem;
    4.    
    5.         protected override void OnUpdate()
    6.         {
    7.             if (disableSomeSystem)
    8.                 someSystem.Enabled = false;
    9.         }
    10.     }
    11.  
    Code (CSharp):
    1.     public class SomeClass : MonoBehaviour
    2.     {
    3.         private void SomeMethod()
    4.         {
    5.             World.Active.GetExistingManager<SomeSystem>().Enabled = false;
    6.         }
    7.     }
    8.  
    But i don't think it is what i'm looking for because i don't want all of my game Gravity system to stop but only the player's one. If i use this, my enemies will also have there Gravity paused.

    I also tried to disable components (because my components are monobehaviour, they have a enable property) but it also didn't worked.


    Thanks by advance.
     
  2. Deleted User

    Deleted User

    Guest

    What you want to do is have some kind of component that the player has while the gravity system should work on him.

    You need to forget that a system works for an entity (i.e. the player). They work for everything that has the correct components. You just need to define what the correct components are.

    So maybe a IsAffectedByGravity Component is what you are searching for.
     
  3. DoYouRockBaby

    DoYouRockBaby

    Joined:
    May 21, 2018
    Posts:
    9
    Ok, so i would have to create a Gravity component with my gravity value and an IsAffectedByGravity component and remove/add the component to enable/disable my system ?

    What about just adding an enabled attribute on my component ?
     
  4. ldhongen1990

    ldhongen1990

    Joined:
    Dec 18, 2015
    Posts:
    61
    Here's how I will code it: We will utilise the ECS system to do hard-lifting filtering for us... Sooo, we think of it as when we want to dash we will add the dash component to the Entity (This is basically a very cheap thing to do in ECS apparently as opposed to traditional Monobehavior AddComponent where GC gets allocated during runtime), then when we are done we will remove it from the entity.

    Data defines the type in ECS, so our DashSystem will only update any entities with the Dash component.
    GravitySystem on the other hand does not want to operate on entity on entities that are dashing, so we use subtractiveComponent to filter those out.

    I am open for suggestions as I am also learning if there is better way to code it.
    Gravity system works independently on everything with a Transform component.

    MovementSystem is basically structured the same way as GravitySystem.

    Code (CSharp):
    1.  
    2. //===================================================
    3. //Put this entire chunk in a new class name PlayerControllerComponent.cs to add to your game object
    4. //To prepare the scene,
    5. //simple create a GameObject,
    6. //add GameObjectEntity and
    7. //Player Controller Component
    8.  
    9. using Unity.Entities;
    10.  
    11. public struct PlayerInputController : IComponentData { }
    12.  
    13. // This wrapper component is currently necessary to add ComponentData to GameObjects.
    14. // In the future we want to make this wrapper component automatic.
    15. public class PlayerControllerComponent : ComponentDataWrapper<PlayerInputController> { }
    16. //===================================================
    17.  
    18.  
    19. using Unity.Entities;
    20. using UnityEngine;
    21. using Unity.Collections;
    22. using Unity.Burst;
    23. using Unity.Jobs;
    24.  
    25.  
    26. public struct Dash : IComponentData
    27. {
    28.     public const float DASH_DURATION = 1f;
    29.     public float timer;
    30.  
    31.     public Dash Init()
    32.     {
    33.         timer = DASH_DURATION;
    34.         return this;
    35.     }
    36. }
    37.  
    38. class PlayerInputSystem : ComponentSystem
    39. {
    40.     struct Entities
    41.     {
    42.         public readonly int Length;
    43.         public EntityArray entities;
    44.         public ComponentDataArray<PlayerInputController> playerInputControllerMarker;
    45.     }
    46.  
    47.     [Inject] private Entities _players;
    48.  
    49.     protected override void OnUpdate()
    50.     {
    51.         if (Input.GetKeyDown(KeyCode.D))
    52.         {
    53.             for (int i = 0; i < _players.Length; ++i)
    54.             {
    55.                 Debug.Log("Dash input detected on Frame: " + Time.frameCount);
    56.                 //Add the Dash component so that the dash system handles the dash
    57.                 PostUpdateCommands.AddComponent(_players.entities[i], new Dash().Init());
    58.             }
    59.         }
    60.     }
    61. }
    62.  
    63. [UpdateAfter(typeof(PlayerInputSystem))]
    64. class DashSystem : ComponentSystem
    65. {
    66.     struct Entities
    67.     {
    68.         public readonly int Length;
    69.         public EntityArray entities;
    70.         public ComponentArray<Transform> transform;
    71.         public ComponentDataArray<Dash> dash;
    72.     }
    73.  
    74.     [Inject] Entities _dashingEntities;
    75.  
    76.     protected override void OnUpdate()
    77.     {
    78.         var dt = Time.deltaTime;
    79.         for (int i = 0; i < _dashingEntities.Length; ++i)
    80.         {
    81.             //Update dashing
    82.             Debug.Log("Dashing on: " + _dashingEntities.transform[i].name + ", Frame: " + Time.frameCount);
    83.  
    84.  
    85.             //Update timer
    86.             var dash = _dashingEntities.dash[i];
    87.             dash.timer -= dt;
    88.  
    89.             if (dash.timer <= 0)
    90.             {
    91.                 //Time to stop dashing
    92.                 PostUpdateCommands.RemoveComponent<Dash>(_dashingEntities.entities[i]);
    93.             }
    94.             else
    95.             {
    96.                 //Write
    97.                 _dashingEntities.dash[i] = dash;
    98.             }
    99.         }
    100.     }
    101. }
    102.  
    103. [UpdateAfter(typeof(PlayerInputSystem))]
    104. class GravitySystem : ComponentSystem
    105. {
    106.     struct Entities
    107.     {
    108.         public readonly int Length;
    109.         public ComponentArray<Transform> transform;
    110.  
    111.         //Exclude entity that are dashing
    112.         SubtractiveComponent<Dash> dash;
    113.     }
    114.  
    115.     [Inject] Entities _entities;
    116.  
    117.     protected override void OnUpdate()
    118.     {
    119.         for (int i = 0; i < _entities.Length; ++i)
    120.         {
    121.             //Update gravity pull
    122.             Debug.Log("Gravity pull on: " + _entities.transform[i].name + ", Frame: " + Time.frameCount);
    123.         }
    124.     }
    125. }
     
  5. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    335
    Use a
    SubtractiveComponent
    whose sole purpose is to declare that an entity should not be processed by some system.

    For example:

    The System:
    GravitySystem

    The SubtractiveComponent:
    DoNotProcessGravityComponent
     
    Antypodish and DoYouRockBaby like this.
  6. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    558
    there is a
    VoidSystem<T>
    component already defined. it is used by the transform system. you can also use this as a convention.

    so your gravity system can declare
    SubtractiveComponent<VoidSystem<GravitySystem>>
    in its group(s)
     
    DoYouRockBaby likes this.
  7. mike_acton

    mike_acton

    Unity Technologies

    Joined:
    Nov 21, 2017
    Posts:
    110
    We're still working out the right convention for this, but yes - we need a standard for globally disable processing on a set of data.
     
  8. ldhongen1990

    ldhongen1990

    Joined:
    Dec 18, 2015
    Posts:
    61
    What does adding SubtractiveComponent<VoidSystem<GravitySystem>> to a GravitySystem group does exactly? I played around with the code but couldn't figure out what it does.
     
    5argon likes this.
  9. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    558
    SubtractiveComponent<T>
    in a group means the group will contain only the entities that don't have that component.

    VoidSystem<T>
    is just a tag and has no special meaning (for now). it's available as a convention (may change) that you can use to be more clear how to explicitly exclude an entity from a system (yes you can define your own "exclude tag" for each of your systems, but then you will have to remember manually what does what ("oh I need to stop FooSystem to process this... what the corresponding tag was called?" vs "let's try VoidSystem<FooSystem> first. if it doesn't work, it means that FooSystem still has no exclusion mechanism, so add it"))

    (another convention you can use is: if a system support entity exclusion, define a nested "ExcludeEntity" component tag, so you
    AddComponent<FooSystem.ExcludeEntity>()
    . but that would be your convention)
     
    5argon likes this.
  10. ldhongen1990

    ldhongen1990

    Joined:
    Dec 18, 2015
    Posts:
    61
    I think I got it now, meaning if I want to stop an Entity from being process by a system now I just need to AddComponent<VoidSystem<GravitySystem>> to the Entity. In this case, I will AddComponent<VoidSystem<GravitySystem>> to the entities that is dashing and when I am done, I will RemoveComponent<VoidSystem<GravitySystem>> from those entities and the GravitySystem should kick in immediately for entities without VoidSystem<GravitySystem> component. Is that right?

    This way, GravitySystem don't even need to keep track of which exact tag to exclude, it is just looking out to process any entities without VoidSystem<GravitySystem> component
     
    5argon likes this.
  11. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    558
    basically yes. your GravitySystem still needs to explicitly exclude
    VoidSystem<GravitySystem>
    from its group(s) though.

    but as @mike_acton said, there may be an 'official' easier and globally consistent way soon™
     
    DoYouRockBaby likes this.
  12. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    Aaaah this is the first good explanation of VoidSystem I ever found... I even read the source code and not able to grasp it until now.

    Basically just that it can change a system name into an attachable component with help of C# generic mechanic so you don't have to name a custom IComponentData, it produce a new name based on class name.

    Now when you read it it would make sense : VoidSystem<A> = Do not process this entity in the system A (I was wondering "what void?" I don't think it is a good name)

    Then in the system A you have to put SubtractiveComponent<VoidSystem<A>> in the inject group so that it does not get processed for real.
     
  13. mike_acton

    mike_acton

    Unity Technologies

    Joined:
    Nov 21, 2017
    Posts:
    110
    Correct.
     
    5argon likes this.