Search Unity

Entity exists test in a job

Discussion in 'Entity Component System' started by xVergilx, Jan 28, 2019.

  1. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Is there a way to test if the entity exists in a job?

    Use case - I want to notify a system (with subtractive component) by removing component from entity when referenced entity doesn't exist anymore.

    E.g.
    I've got entity reference like so:
    Code (CSharp):
    1.  public struct EntityReference : IComponentData {
    2.         public Entity Entity;
    3. }
    I want to remove the EntityReference component when the entity is being removed.
    How do I check if entity exists?

    Or it is better to do a reverse, e.g. attach the EntityReference to the created entity, and when it being removed notify referencer by setting a component onto it?
     
    Last edited: Jan 28, 2019
  2. kork

    kork

    Joined:
    Jul 14, 2009
    Posts:
    280
    I think the way jobs work there is no real safe way to check if an entity exists in a job. I would approach this by having a system that is responsible for destroying the entities and is taking care killing all entity references together with the destroyed entity. It's somewhat frustrating that we have no real reactive systems in Unity ECS which would make this thing a bit easier to implement.
     
    FROS7 and xVergilx like this.
  3. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    BufferFromEntity, ComponentDataFromEntity has Exists method for check Entity existance (in archetype which enougth for check in much cases).

    ECS has reactive system implementation by ISystemStateComponent, DidChange, DidAddOrChange, WorldDiff and other.
     
    ocnenued, touzov and xVergilx like this.
  4. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Interesting, can you give an example on how to use BufferFromEntity?
     
  5. kork

    kork

    Joined:
    Jul 14, 2009
    Posts:
    280
    Well technically,
    BufferFromEntity
    and
    ComponentDataFromEntity
    allow you to check if a component/buffer exists on an entity. It doesn't allow you to check if the entity itself exists.

    Basically it works like this. In your job system you get the
    BufferFromEntity
    /
    ComponentDataFromEntity
    object:

    Code (CSharp):
    1. var componentDataFromEntity =GetComponentDataFromEntity<MyComponent>();
    2.  
    3. // then call your job
    4.  
    5. new MyJob {
    6.    ComponentDataFromEntity = componentDataFromEntity,
    7.     ...
    8. }.Schedule(...)
    9.  
    10. // and in the job itself.
    11.  
    12. if (ComponentDataFromEntity.Exists(myEntity)) {
    13.    // myEntity has a MyComponent component
    14. }
    15.  
    For buffers this is similar. So if you make like a marker component to identify a living entity, you can use this to track if the entity exists.
     
    Last edited: Jan 29, 2019
    NotaNaN and xVergilx like this.
  6. kork

    kork

    Joined:
    Jul 14, 2009
    Posts:
    280
    Yes, but it's a lot of legwork you have to do, sometimes distributed over multiple systems. Also you have a lot of cognitive overhead juggling multiple marker components to somehow track changes, which is fine in an isolated example but becomes harder to do the more complex your game gets. Other ECS implementations offer callbacks on changes which make this sort of thing much easier. I know that callbacks are not really going to fly with this architecture, but oftentimes I wish there were less convoluted and more reliable (looking at you
    SetFilterChanged
    ) ways to find out if a component changed or an entity disappeared.
     
    NotaNaN, e199 and xVergilx like this.
  7. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    If you do stuff with some chunks you absolutley shure in ther archetype and just one row GetComponentDataFromEntity and one field in job it's fast and simple solution for checking existance. Moreover you must use more atomic jobs, which not depend on complexity of your game. Our game very complex and there is no problems with ComponentDataFromEntity (https://forum.unity.com/threads/unity-ecs-and-job-system-in-production.561229/)

    DidChange DidAddOrChange and ChunkIteration based logic better for me.
     
    Last edited: Jan 29, 2019
  8. kork

    kork

    Joined:
    Jul 14, 2009
    Posts:
    280
    This. I am still in the "banging my head against the wall"-phase. Apparently you have already established some patterns on how to solve specific problems given the facilities that ECS currently offers. These patterns I still need to discover.
     
    xVergilx likes this.
  9. tiggus

    tiggus

    Joined:
    Sep 2, 2010
    Posts:
    1,240

    I am right there with you :) Right now I am not even looking at jobs I am just wrapping head around ECS using pure ComponentSystems. ECS + jobs all at once seems like a lot to tackle. Now that I see things like this question though it looks like I will have to refactor quite a bit when adding jobs into the mix.
     
  10. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Jobs are actually easy, bursting them not so much.

    Also, entity checks.
     
  11. touzov

    touzov

    Joined:
    Feb 19, 2017
    Posts:
    4
    Thank you. You solved my problem.
     
  12. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    I will necro this thread because it is the first Google result and
    ComponentDataFromEntity.Exists(myEntity)
    is now deprecated
     
  13. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    260
    It has been replaced with ComponentDataFromEntity.HasComponent(e).
     
    josefloresvargas likes this.
  14. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    That checks if "instance still refers to a valid entity and that it has a component of type T"
    I just want to know if "instance still refers to a valid entity" and nothing else
     
  15. julian-moschuering

    julian-moschuering

    Joined:
    Apr 15, 2014
    Posts:
    529
    I believe it was only renamed to make it clear what it does. It never did what you expected.

    var matchAny = EntityManager.GetEntityQueryMask(EntityManager.UniversalQuery);
    var exists = matchAny.Matches(entity);
     
    bilalakil likes this.
  16. Gekigengar

    Gekigengar

    Joined:
    Jan 20, 2013
    Posts:
    738
    This went obsolete since, how to do this in 1.0ex?

    EDIT: Nvm, found easy way.
    Code (CSharp):
    1. EntityManager.Exists(e);
     
  17. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    EntityManager.Exists
    is for main thread only, for jobs you should use
    EntityStorageInfoLookup
    .
    upload_2022-10-18_12-50-43.png