Adding elements to DynamicBuffer in Entities.ForEach()

I want to add a newly created testEntity to the LinkedEntityGroup of MyCarEntity.
As soon as MyCarEntity gets destroyed, **testEntity “**should” get destroyed too.
This code works, but as soon as I destroy MyCarEntity, testEntity still exists.

public class MySystem : SystemBase
{
     private BeginInitializationEntityCommandBufferSystem m_EntityCommandBufferSystem;
 
     protected override void OnCreate() {
          this.m_EntityCommandBufferSystem = this.World.GetOrCreateSystem<BeginInitializationEntityCommandBufferSystem>();
     }

     protected override void OnUpdate() {
          EntityCommandBuffer commandBuffer = this.m_EntityCommandBufferSystem.CreateCommandBuffer();

          this.Entities
               .ForEach((
               Entity MyCarEntity,
               ref DynamicBuffer<LinkedEntityGroup> linkedEntityGroup
          ) => {
               Entity testEntity = commandBuffer.CreateEntity();
               linkedEntityGroup.Add(testEntity);
          }).WithoutBurst().Run();

          this.m_EntityCommandBufferSystem.AddJobHandleForProducer(this.Dependency);
     }
}

If I check my Entity Debugger, testEntity also exists there after destroying MyCarEntity.
And if I go to the last page of LinkedEntityGroup of MyCarEntity (before destroying), the editor window gets somehow broken (in Unity 2021.1.0b6).
Also the index of testEntity is displayed wrong there, its displayed as “-8”? (But actual testEntity has id 231)

Has someone an idea what could be wrong here? Why is testEntity still existing after destroying MyCarEntity? And whats happened to the editor?

Most likely you have assigned entity, just after ECB have instantiated it (still in the same frame).
Meaning entity does not exist yet, but have temp entity index as negative value.

So you assign entity with negative index. Frame later entity is created, but the reference stays invalid.
You should assign entities, after ECB is played back / next frame.

1 Like

Replace linkedEntityGroup.Add(testEntity); with commandBuffer.AppendToBuffer(MyCarEntity, new LinkedEntityGroup { Value = testEntity });

3 Likes

Thank you @Antypodish & @TRS6123 !!

Thanks for the explanation. That makes totally sense, but it also means a lot of extra work or? I thought maybe about an extra system for this, which looks for an extra component on testEntity, which holds the Entity to add the buffer item later on…

That worked perfectly! Thanks for this suggestion :slight_smile: Nice to know that there are already some build-in solutions for such cases ^^

In such cases, sometimes I have component on new entity, called AddToParentComponent, with parent entity as value. This component is added by ecb, or is part of instantiated prefab via ecb. Just need set parent entity to that component, which is assumed to exist.

Then there is separate job, which executes only for entities with that component.
It handles parent addition and maybe some relevant tasks, if required.
At the same job, I remove that component, so job is not called anymore for that entity.

The down side is, this may create frame to two frames delay, depending on the design.