Search Unity

[Bug] Accessing object component after destroy entity

Discussion in 'Entity Component System' started by alexnown, Apr 23, 2019.

  1. alexnown

    alexnown

    Joined:
    Oct 25, 2018
    Posts:
    22
    I'm discovered a strange behaviour after destroying entities from native list. In my game I'm add all entities, which needs to be destroed to native list and call EntityManager.DestroyEntity(DestroyEntitiesList) from DestroySystem. If destroyed entities have managed component, I can access some component from another exists entity in same chunk.
    Simple example:
    entity0: MyMonoBehaviour with id = 1 (destroing frame = 1)
    entity1: MyMonoBehaviour with id = 2 (destroing frame = 1)
    entity2: MyMonoBehaviour with id = 3 (destroing frame = 3)

    Code (CSharp):
    1. Entities.ForEach((Entity e, MyMonoBehaviour monoBeh, ref DestructionTime frame) =>
    2. {
    3.      if (frame.Value != Time.frameCount) return;
    4.      _destroySystem.DestroyEntitiesList.Add(e);
    5.      Debug.Log($"{Time.frameCount} frame: Destroy entity index={e.Index} with component id={monoBeh.Id}, already destroyed={monoBeh == null}");
    6.      Object.Destroy(monoBeh.gameObject);
    7. });
    entity0 and entity1 were destroyed at 1 frame, after entity2 has a link to the mono component from entity1 that has already been destroyed.
    upload_2019-4-23_22-59-15.png
     
  2. alexnown

    alexnown

    Joined:
    Oct 25, 2018
    Posts:
    22
    Unity 2019.1.0f2, entities-p30
    Project with simple example
     

    Attached Files:

  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    ComponentObjects are reference types. Destroying the entity does not destroy the object on the GC managed heap, hence another entity's ComponentObject can still reference them. Use a reactive system and call Destroy if you truly want to destroy the ComponentObject, or even better pool your ComponentObject and release it to the pool in your reactive system.
     
  4. alexnown

    alexnown

    Joined:
    Oct 25, 2018
    Posts:
    22
    DreamingImLatios, thanks for the reply. The main question is how I got not expected reference to a object.
    This behavior only happens after using batch destroying by NativeList.

    At my example I'm added managed component with id=3 to entity2. After deleting some entities(more than one at same frame), entity2 in ForEach loop got reference to wrong managed component(with id=2).
     
    Last edited: Apr 24, 2019
  5. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    Sorry. I misread what was going on. It doesn't seem like my computer wants to open your archive.