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

Discussion EntityManager.Exists is unreliable

Discussion in 'Entity Component System' started by Richay, Aug 9, 2023.

  1. Richay

    Richay

    Joined:
    Aug 5, 2013
    Posts:
    72
    I've just spent a while debugging why my Exists checks are returning true after explicitly calling Destroy on them. It took stumbling upon the ICleanupComponentData documentation to realise what was happening: a Netcode component was preventing the entity from being registered as destroyed. Worse, my component lookup for checking the value of an enabled component was throwing "component not found on entity" exceptions - all components except the cleanup components had been removed.

    In my opinion, this completely goes against expectations, and renders certain key functionality as unreliable. You simply cannot rely on Exists, IsComponentEnabled, etc. for entities you know which may/will be destroyed. And since cleanup components can be added to an entity from other packages (e.g. Netcode), you have no explicit knowledge that they're there, and once known, you have to rejig your checks. As a workaround, I've added a tag component to all destroyable entities, which I check the existence of instead of calling Exists.

    I feel that calling Destroy should register an entity as destroyed, no exceptions. For cleanup components, having a "WithDestroyed" option in the query (in the same manner as when dealing with prefabs, system entities, etc) would be clean and straightforward.

    Thoughts?
     
    UniqueCode and JesOb like this.
  2. msfredb7

    msfredb7

    Joined:
    Nov 1, 2012
    Posts:
    143
    So EntityManager.Exists(myEntity) could return false, even if the entity does exist in memory? This could also be viewed as "counter to expectations".

    I believe this is what the DOTS team intended users to do. Personally, I recommend using HasComponent/HasBuffer over EntityManager.Exists, when possible.
     
  3. Richay

    Richay

    Joined:
    Aug 5, 2013
    Posts:
    72
    Yes, the same as prefabs, system handles, etc are hidden from queries by default. I cannot imagine that the current manner of explicitly calling DestroyEntity(e), then finding Exists(e) == true to be more intuitive than using the same pattern of accessing "special" entities.

    Is there a link to this in the docs? I find it hard to believe, and even if so, it doesn't address the unreliability of Exists.
     
  4. msfredb7

    msfredb7

    Joined:
    Nov 1, 2012
    Posts:
    143
    One of the pillars traditional ECS is no (or very little) data abstraction. ECS wants the programmer to be aware of how the memory works. That's probably why Unity used a different approach than with GameObjects.
    No, pure speculation on my part.
    It is only unreliable when you think of Exists(entity) as a NotDestroyed(entity) method. This might be what Unity intended at first, but as you said, with cleanup components, that's not what Exists means anymore. To me, it's become intuitive.
     
  5. Richay

    Richay

    Joined:
    Aug 5, 2013
    Posts:
    72
    When you spend several hours trying to narrow down a bug simply because Exists didn't return as expected, because the netcode package added a cleanup component, I would disagree that the function is intuitive.
     
  6. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,081
    I Think it is like go.activeSelf vs go.activeInHierarchy methods

    so we need 2 methods like ExistsNow and ExistsAndNotMarkedForDestroy <- may be some shorter name
     
    apkdev and msfredb7 like this.
  7. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    You shouldn't really check against if Entity exists. Check against required data instead. This is more robust.
    Non cleanup components are always removed.
     
    apkdev likes this.
  8. Richay

    Richay

    Joined:
    Aug 5, 2013
    Posts:
    72
    Yes, this is the reason I made this post. Checking for known non-cleanup components feels wrong when I simply need to know if an entity exists. It's non-intuitive.
     
    apkdev likes this.