Search Unity

EntityManager.Exists returns true after Entity was destroyed?

Discussion in 'Entity Component System' started by Wobbers, Jan 20, 2020.

  1. Wobbers

    Wobbers

    Joined:
    Dec 31, 2017
    Posts:
    55
    So I have a ComponentSystem that destroys Entities and one that checks components on Entities. The destroy-System runs shortly before the check-System (but both are ComponentSystems, so both on the Main Thread, right?)

    Now when I am checking the Components of an Entity that was destroyed the same frame, EntityManager.Exists returns true, but the Component of the Entity I am trying to access already got removed, so I get an
    Code (CSharp):
    1. ArgumentException: A component with type:Translation has not been added to the entity.
    Is this a bug or are there some multithreaded/other things going on that have to be kept in mind when using EntityManager.Exists?

    (Using Entities 0.5.0)

    Code:
    Code (CSharp):
    1. // Runs first
    2. public class DeathSystem : ComponentSystem
    3. {
    4.     protected override void OnUpdate()
    5.     {
    6.         Entities.ForEach((Entity e, ref Health health) =>
    7.         {
    8.             if (health.Value <= 0)
    9.             {
    10.                 Debug.Log("Entity Died: " + e);
    11.                 EntityManager.DestroyEntity(e);
    12.                 // Same result with PostUpdateCommands.DestroyEntity(e)
    13.             }
    14.         });
    15.     }
    16. }
    Code (CSharp):
    1. // Runs second
    2. public class DummyKISystem : ComponentSystem
    3. {
    4.     protected override void OnUpdate()
    5.     {
    6.         Entities.ForEach((ref DummyKIComponent dummy, ref Translation translation, ref Rotation rotation, ref MovementSpeed speed) =>
    7.         {
    8.             if (dummy.CurrentTarget == Entity.Null)
    9.             {
    10.                 ...
    11.             }
    12.             else if (!EntityManager.Exists(dummy.CurrentTarget))
    13.                 dummy.CurrentTarget = Entity.Null;
    14.             else
    15.             {                
    16.                 if (!EntityManager.HasComponent<Translation>(dummy.CurrentTarget))
    17.                     Logger.Log("Blargh! " + dummy.CurrentTarget);
    18.                 // ... (Access Translation Component)
    19.             }
    20.         });
    21.     }
    22. }
    Result:
    upload_2020-1-20_23-7-50.png
     
  2. edalbeci

    edalbeci

    Joined:
    Jan 21, 2018
    Posts:
    36
    I unfortunately don't have a solution, but did you omit or forget a [UpdateBefore(typeof(DeathSystem))] for DummyKISystem? I don't know about ForEach but PostUpdateCommands is definitely run on the main thread, sequentially, per the official Command Buffer docs.

    To remove the possibility of a race condition, I made just one system:

    Code (CSharp):
    1. public class TestComponentSystem : ComponentSystem {
    2.  
    3.     protected override void OnUpdate()
    4.     {
    5.         int n = 0;
    6.         Entities.ForEach((Entity e) =>
    7.         {
    8.             UnityEngine.Debug.Log(EntityManager.Exists(e));
    9.             PostUpdateCommands.DestroyEntity(e);
    10.             n++;
    11.         });
    12.         UnityEngine.Debug.Log(n);
    13.     }
    14. }
    The output is consistent with yours though -- the entity is, oddly enough, never destroyed. (The system continues to iterate over the same entities, even after the update function completes and the next frame is run)

     
  3. schaefsky

    schaefsky

    Joined:
    Aug 11, 2013
    Posts:
    90
    I am having the same problem, did you find a solution?
     
  4. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,708
    I would think that the second system would implicitly create a entity query in the lambda so that you don’t have to use the EntiyManager inside the function.
     
  5. Wobbers

    Wobbers

    Joined:
    Dec 31, 2017
    Posts:
    55
    tagergo and schaefsky like this.