Search Unity

Can't access LinkedEntityGroup

Discussion in 'Entity Component System' started by vectorized-runner, Mar 5, 2020.

  1. vectorized-runner

    vectorized-runner

    Joined:
    Jan 22, 2018
    Posts:
    398
    I'm trying to make a system that gets all entities with OptimizeTag and removes unnecessary components from them.

    For some reason I can't get the LinkedEntityGroup, but the Entity Debugger shows that all entities with OptimizeTag has LinkedEntityGroup.

    Accessing the LinkedEntityGroup throws this error: InvalidOperationException: The NativeArray has been deallocated, it is not allowed to access it.

    Any idea why is this happening?

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Mathematics;
    3. using Unity.Rendering;
    4. using Unity.Transforms;
    5. using Hash128 = Unity.Entities.Hash128;
    6.  
    7. public class OptimizeSystem : ComponentSystem
    8. {
    9.     protected override void OnUpdate()
    10.     {
    11.  
    12.         Entities.ForEach((Entity entity, ref OptimizeTag optimizeTag) =>
    13.         {
    14.             var linkedEntityGroup = EntityManager.GetBuffer<LinkedEntityGroup>(entity);
    15.  
    16.             for(int i = 0; i < linkedEntityGroup.Length; i++)
    17.             {
    18.                 var childEntity = linkedEntityGroup[i].Value;
    19.                 EntityManager.AddComponent(childEntity, typeof(Static));
    20.                 EntityManager.AddComponent(childEntity, typeof(Frozen));
    21.                 EntityManager.RemoveComponent(childEntity, typeof(Translation));
    22.                 EntityManager.RemoveComponent(childEntity, typeof(Rotation));
    23.                 EntityManager.RemoveComponent(childEntity, typeof(LocalToParent));
    24.                 EntityManager.RemoveComponent(childEntity, typeof(Child));
    25.                 EntityManager.RemoveComponent(childEntity, typeof(Parent));
    26.                 EntityManager.RemoveComponent(childEntity, typeof(PreviousParent));
    27.              
    28.                 if(EntityManager.HasComponent<RenderMesh>(childEntity))
    29.                 {
    30.                     EntityManager.AddSharedComponentData(childEntity, new FrozenRenderSceneTag
    31.                     {
    32.                         SceneGUID = new Hash128 { Value = new uint4(1, 0, 0, 0) }
    33.                     });
    34.                 }
    35.  
    36.                 // Remove OptimizeTag, after the object is finished
    37.                 EntityManager.RemoveComponent(childEntity, typeof(OptimizeTag));
    38.             }
    39.         });
    40.     }
    41. }
     
    Last edited: Mar 5, 2020
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    You're doing structural changes, which invalidate all direct references to any component data. You can easily see it if put debugger in to your for loop, it will print only first iteration (and second if you put it before
    linkedEntityGroup[i].value
    line). In your case
    linkedEntityGroup
    buffer invalidated right in first
    EntityManager.AddComponent
    call. You can use ECB for defer synch point after loop, or just do
    ToNativeArray
    after
    GetBuffer
    thus you get copy and not reference which wouldn't be invalidated.
     
    Last edited: Mar 6, 2020
    vectorized-runner likes this.