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

Request: ISystemStateBufferElementData

Discussion in 'Entity Component System' started by Jay-Pavlina, Jan 25, 2019.

  1. Jay-Pavlina

    Jay-Pavlina

    Joined:
    Feb 19, 2012
    Posts:
    195
    It would be good to have a system state version of IBufferElementData. A use case would be to destroy all children of an entity when it is destroyed. I am storing children in an IBufferElementData.
     
  2. RecursiveEclipse

    RecursiveEclipse

    Joined:
    Sep 6, 2018
    Posts:
    298
    To suggest an alternative, this is a system I use to destroy my child entities. It uses TransformSystem's ParentToChildTree MultiHashMap, which tracks all children for a parent:

    Code (CSharp):
    1. [UpdateAfter(typeof(TransformSystem))]
    2. [UpdateBefore(typeof(EndFrameBarrier))]
    3. public class DestroyHierarchySystem : JobComponentSystem {
    4.     [Inject] EndFrameBarrier barrier;
    5.     bool isInitialized;
    6.     NativeMultiHashMap<Entity, Entity> parentToChildTree;
    7.    
    8.     void Init() {
    9.         //Using reflection to get the existing ParentToChildTree HashMap of TransformSystem.
    10.         var transformSystem = World.GetExistingManager<TransformSystem>();
    11.         var parentToChildInfo = typeof(TransformSystem).GetField(
    12.             "ParentToChildTree", BindingFlags.NonPublic | BindingFlags.Instance);
    13.         parentToChildTree = (NativeMultiHashMap<Entity, Entity>)parentToChildInfo.GetValue(transformSystem);
    14.         isInitialized = true;
    15.     }
    16.  
    17.     [BurstCompile]
    18.     struct DestroyHierarchyJob : IJobProcessComponentDataWithEntity<DestroyEntityTag> {
    19.         public EntityCommandBuffer.Concurrent CommandBuffer;
    20.         [ReadOnly] public NativeMultiHashMap<Entity, Entity> ParentToChildTree;
    21.         [ReadOnly] public ComponentDataFromEntity<DestroyEntityTag> DestroyEntityTags;
    22.        
    23.         public void Execute(Entity entity, int jobIndex, [ReadOnly] ref DestroyEntityTag tag) {
    24.             DestroyTreeIterative(jobIndex, entity);
    25.         }
    26.        
    27.         void DestroyTreeIterative(int jobIndex, Entity parent) {
    28.             CommandBuffer.DestroyEntity(jobIndex, parent);
    29.             if(!ParentToChildTree.TryGetFirstValue(parent, out Entity foundChild, out var iterator)) {
    30.                 return;
    31.             }
    32.             do {
    33.                 DestroyTreeIterative(jobIndex, foundChild);
    34.                 //Check that child does not already have a tag so it is not deleted twice.
    35.                 if(!DestroyEntityTags.Exists(foundChild)) {
    36.                     CommandBuffer.DestroyEntity(jobIndex, foundChild);
    37.                 }
    38.             } while(ParentToChildTree.TryGetNextValue(out foundChild, ref iterator));
    39.         }
    40.     }
    41.  
    42.     protected override JobHandle OnUpdate(JobHandle inputDeps) {
    43.         if(!isInitialized) {
    44.             Init();
    45.         }
    46.         return new DestroyHierarchyJob {
    47.             CommandBuffer = barrier.CreateCommandBuffer().ToConcurrent(),
    48.             ParentToChildTree = parentToChildTree,
    49.             DestroyEntityTags = GetComponentDataFromEntity<DestroyEntityTag>(isReadOnly:true)
    50.         }.Schedule(this, inputDeps);
    51.     }
    52. }
    I just add DestroyEntityTag component to the parent in the hierarchy where I want to destroy, when TransformSystem runs again it cleans up the hashmap for me.
     
  3. Jay-Pavlina

    Jay-Pavlina

    Joined:
    Feb 19, 2012
    Posts:
    195
    I appreciate it but I have already implemented an alternative. It was just an example use case to justify the request. There will always be alternate ways to do things but I think it’s a valid request and fits well with the existing API. I think dynamic buffers should have all of the same features as component data.
     
    nicolasgramlich and JesOb like this.