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. Dismiss Notice

Question Is there any way to RequireNoneForUpdate?

Discussion in 'Entity Component System' started by Krooq, Mar 26, 2022.

  1. Krooq

    Krooq

    Joined:
    Jan 30, 2013
    Posts:
    180
    Wondering if there is a way to do RequireNoneForUpdate in a system?

    I could always add a dummy component to some entity then delete that entity, but I would need to create a new type or every instance or sling it onto another entity with a type that I care about.
    It's also sorta defeats the purpose.

    The use case is a system that only ever runs the once to do some initialization.
     
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    Just put EntityQuery with None to RequireForUpdate.
     
  3. Krooq

    Krooq

    Joined:
    Jan 30, 2013
    Posts:
    180
    Before posting I did try this:
    Code (CSharp):
    1. var query = new EntityQueryDescBuilder();
    2. query.AddNone(typeof(ClientID));
    3. query.FinalizeQuery();
    4. RequireForUpdate(EntityManager.CreateEntityQuery(query));
    But got some strange errors, so I just assumed I misunderstood the purpose of this API.

    After actually reading the manual here https://docs.unity3d.com/Packages/com.unity.entities@0.50/manual/ecs_entity_query.html
    I tried this:
    Code (CSharp):
    1. var query = new EntityQueryDesc
    2. {
    3.     None = new ComponentType[] { typeof(ClientID) }
    4. };
    5. RequireForUpdate(GetEntityQuery(query));
    Which runs without errors but doesn't do what I need.
     
    Last edited: Mar 26, 2022
  4. Krooq

    Krooq

    Joined:
    Jan 30, 2013
    Posts:
    180
    After looking into the source code, I'm not actually sure it's possible...

    In class SystemState it has the follow method which checks if a system can run
    Code (CSharp):
    1.        
    2. internal bool ShouldRunSystem()
    3. {
    4.     if (AlwaysUpdateSystem)
    5.         return true;
    6.  
    7.     ref var required = ref RequiredEntityQueries;
    8.  
    9.     if (required.Length > 0)
    10.     {
    11.         for (int i = 0; i != required.Length; i++)
    12.         {
    13.             EntityQuery query = required[i];
    14.             if (query.IsEmptyIgnoreFilter)
    15.                 return false;
    16.         }
    17.  
    18.         return true;
    19.     }
    20. ...
    21.  
    Here it requires that the EntityQuery must match some entities to pass.
    What I'm looking for is that is matches no entities.

    @eizenhorn I believe your suggestion would only check that there is at least one entity that does not have the component.
     
  5. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    If you use default bootstrap then there always will be entities (world time for example). But anyway, if you want use your system only once for data initialisation you can just mark system as always update, in OnUpdate check your condition (there is no entities with component you interested in) and the disable that system (Enabled property)
     
    Krooq likes this.
  6. Krooq

    Krooq

    Joined:
    Jan 30, 2013
    Posts:
    180
    Doh, dunno why I didn't think of the Enabled property!
     
  7. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,266
    It would be great if RequireForUpdate honored the state of Enableable components in an EntityQuery. Setting a system as disabled means managing the state of a bunch of init systems when you want to init again, unless I'm missing something?
     
  8. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,626
    You really don't want this as it would require a sync point.

    Enable states can be changed in a job therefore you would need to complete all jobs in the chain that could possibly edit the enable state before you can determine if the system should run on main thread.
     
    apkdev likes this.
  9. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,266
    Thanks for clarifying the context. So from your experience, is there a best standard workflow for initializing data after baking? I have been mulling a couple of strategies:
    1. Accept the one-time structural change of removing a "RequiresInit" tag, or something similar, from an entity that requires initialization.
    2. Disable the init system after first run; fetch it via handle later should it need to be reenabled (restarting, respawning, instantiating new entities that need init, etc).
    3. Something else?