Search Unity

Information about separate entity in IJobChunk

Discussion in 'Entity Component System' started by e199, Nov 28, 2018.

  1. e199

    e199

    Joined:
    Mar 24, 2015
    Posts:
    101
    Hey

    I'm iterating over all entities which got "TriggerEnter" component attached (component acts as event, it will be removed at the end of frame)
    In that component I have trigger entity we collided with.

    In the job I want to check if that entity has some kind of component ("Flamed" in my case) and if it does, then continue our job and change data on our "local" entity.

    What approach can you suggest?

    I was thinking about pushing that information to the "TriggerEnter" component, but as features add that component would inflate too much.
    Second Idea was to store archetype of trigger entity into "TriggerEnter" component, but I was not able to find the way to get it.

    Code (CSharp):
    1.  
    2. using System;
    3. using Unity.Collections;
    4. using Unity.Entities;
    5. using Unity.Jobs;
    6.  
    7. [UpdateAfter(typeof(PhysicsEventEmissionBarrier))]
    8. public class AddHeatingSystem : JobComponentSystem
    9. {
    10.     private ComponentGroup _query;
    11.  
    12. protected override void OnCreateManager()
    13. {
    14.     _query = GetComponentGroup(new EntityArchetypeQuery
    15.     {
    16.         All  = new[] {ComponentType.ReadOnly<TriggerEnter>(), ComponentType.ReadOnly<Flamable>()},
    17.         None = Array.Empty<ComponentType>(),
    18.         Any  = Array.Empty<ComponentType>()
    19.     }, new EntityArchetypeQuery
    20.     {
    21.         All  = new[] {ComponentType.ReadOnly<TriggerEnter>(), ComponentType.ReadOnly<Flamable>(), ComponentType.Create<Heating>()},
    22.         None = Array.Empty<ComponentType>(),
    23.         Any  = Array.Empty<ComponentType>()
    24.     });
    25. }
    26.  
    27.     private struct AddHeating : IJobChunk
    28.     {
    29.         public EntityCommandBuffer.Concurrent Commands;
    30.  
    31.         public            ArchetypeChunkEntityType                  EntityType;
    32.         [ReadOnly] public ArchetypeChunkComponentType<TriggerEnter> TriggerEnterType;
    33.         public            ArchetypeChunkComponentType<Heating>      HeatingType;
    34.  
    35.         public void Execute(ArchetypeChunk chunk, int chunkIndex)
    36.         {
    37.             var entityArray  = chunk.GetNativeArray(EntityType);
    38.             var triggerArray = chunk.GetNativeArray(TriggerEnterType);
    39.             var heatArray    = chunk.GetNativeArray(HeatingType);
    40.  
    41.             var hasHeat = heatArray.Length > 0;
    42.  
    43.             for (int i = 0; i < triggerArray.Length; i++)
    44.             {
    45.                 var triggerEntity = triggerArray[i].Trigger;
    46.  
    47.                 *****************
    48.                 //IF TRIGGER ENTITY HAS COMPONENT "FLAMED", then do work
    49.                 if (!triggerEntity.HasComponent<Flamed>)
    50.                     continue;
    51.                 ******************
    52.  
    53.                 if (hasHeat)
    54.                 {
    55.                     //increment counter
    56.                 }
    57.                 else
    58.                 {
    59.                     //add Heating with value of 1
    60.                 }
    61.             }
    62.         }
    63.     }
    64.  
    65.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    66.     {
    67.         return new AddHeating
    68.         {
    69.             EntityType       = GetArchetypeChunkEntityType(),
    70.             TriggerEnterType = GetArchetypeChunkComponentType<TriggerEnter>(),
    71.             HeatingType      = GetArchetypeChunkComponentType<Heating>()
    72.         }.Schedule(_query, inputDeps);
    73.     }
    74. }
    75.  

    Code (CSharp):
    1.  
    2. using System;
    3. using Unity.Entities;
    4.  
    5. [Serializable]
    6. public struct Flamable : IComponentData
    7. {
    8.     //Min temperature to be flamed
    9.     public float Temperature;
    10. }
    11. public struct Flamed : IComponentData{}
    12.  
    13. [Serializable]
    14. public struct Temperature : IComponentData
    15. {
    16.     public float Value;
    17. }
    18.  
    19. public struct Heating : IComponentData
    20. {
    21.     //Amount ot heat sources infuencing that entity
    22.     public int Count;
    23. }
    24.  
    25. [UpdateBefore(typeof(EndFrameBarrier))]
    26. public class PhysicsEventRemoveBarrier : BarrierSystem{}
    27.  
    28. [UpdateBefore(typeof(PhysicsEventRemoveBarrier))]
    29. public class PhysicsEventEmissionBarrier : BarrierSystem{}
    30.  
    31. public struct TriggerEnter : IComponentData
    32. {
    33.     public Entity Trigger;
    34. }
    35.  
    36. public struct TriggerExit : IComponentData
    37. {
    38.     public Entity Trigger;
    39. }
    40.  
    41. public struct CollisionEnter : IComponentData
    42. {
    43.     public Entity Trigger;
    44.     public float3 Position;
    45.     public float3 Normal;
    46. }
    47.  
    48. public struct CollisionExit : IComponentData
    49. {
    50.     public Entity Trigger;
    51. }
    52.  
     
    Last edited: Nov 28, 2018
  2. dartriminis

    dartriminis

    Joined:
    Feb 3, 2017
    Posts:
    157
    Couldn't you just use:
    ComponentDataFromEntity<Flamed>.Exists(triggerEntity)


    EDIT: Fixed syntax.
     
    e199 likes this.
  3. e199

    e199

    Joined:
    Mar 24, 2015
    Posts:
    101
    Thanks, it looks exactly like what I want.

    But when I put it into jobs - it doesn't work. It's not clear from the docs where it should be placed..



    Code (CSharp):
    1. using System;
    2. using Unity.Collections;
    3. using Unity.Collections.LowLevel.Unsafe;
    4. using Unity.Entities;
    5. using Unity.Jobs;
    6.  
    7. [UpdateAfter(typeof(PhysicsEventEmissionBarrier))]
    8. public class AddHeatingSystem : JobComponentSystem
    9. {
    10.     private ComponentGroup _query;
    11.  
    12.     protected override void OnCreateManager()
    13.     {
    14.         _query = GetComponentGroup(new EntityArchetypeQuery
    15.         {
    16.             All  = new[] {ComponentType.ReadOnly<TriggerEnter>(), ComponentType.ReadOnly<Flamable>()},
    17.             None = Array.Empty<ComponentType>(),
    18.             Any  = Array.Empty<ComponentType>()
    19.         }, new EntityArchetypeQuery
    20.         {
    21.             All  = new[] {ComponentType.ReadOnly<TriggerEnter>(), ComponentType.ReadOnly<Flamable>(), ComponentType.Create<Heating>()},
    22.             None = Array.Empty<ComponentType>(),
    23.             Any  = Array.Empty<ComponentType>()
    24.         });
    25.     }
    26.  
    27.     private struct AddHeating : IJobChunk
    28.     {
    29.         public EntityCommandBuffer.Concurrent Commands;
    30.  
    31.         [ReadOnly] public            ArchetypeChunkEntityType                  EntityType;
    32.         [ReadOnly] public ArchetypeChunkComponentType<TriggerEnter> TriggerEnterType;
    33.         public            ArchetypeChunkComponentType<Heating>      HeatingType;
    34.      
    35.         [NativeSetThreadIndex] private int _threadIndex;
    36.      
    37.         [ReadOnly] [Inject] private ComponentDataFromEntity<Flamed> _flamedEntities;
    38.  
    39.         public void Execute(ArchetypeChunk chunk, int chunkIndex)
    40.         {
    41.             var entityArray  = chunk.GetNativeArray(EntityType);
    42.             var triggerArray = chunk.GetNativeArray(TriggerEnterType);
    43.             var heatArray    = chunk.GetNativeArray(HeatingType);
    44.  
    45.             var hasHeat = heatArray.Length > 0;
    46.  
    47.             for (int i = 0; i < triggerArray.Length; i++)
    48.             {
    49.                 var entity = entityArray[i];
    50.                 var triggerEntity = triggerArray[i].Trigger;
    51.  
    52.                 if (_flamedEntities.Exists(triggerEntity))
    53.                 {
    54.                     if (hasHeat)
    55.                     {
    56.                         var heat = heatArray[i];
    57.                         heat.Count++;
    58.                         Commands.SetComponent(_threadIndex, entity, heat);
    59.                     }
    60.                     else
    61.                     {
    62.                         Commands.AddComponent(_threadIndex, entity, new Heating{Count = 1});
    63.                     }
    64.                 }
    65.             }
    66.         }
    67.     }
    68.  
    69.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    70.     {
    71.         return new AddHeating
    72.         {
    73.             EntityType       = GetArchetypeChunkEntityType(),
    74.             TriggerEnterType = GetArchetypeChunkComponentType<TriggerEnter>(),
    75.             HeatingType      = GetArchetypeChunkComponentType<Heating>()
    76.         }.Schedule(_query, inputDeps);
    77.     }
    78. }
     
  4. e199

    e199

    Joined:
    Mar 24, 2015
    Posts:
    101
    Alright, looks like I need to
    Write this in System:

    [ReadOnly] [Inject] public ComponentDataFromEntity<Flamed> FlamedEntities;


    And pass it to Job in OnUpdate by hand
     
  5. dartriminis

    dartriminis

    Joined:
    Feb 3, 2017
    Posts:
    157
    Correct. There should also be a GetComponentDataFromEntity<T> method in the ComponentSystem class that you can call in Update().
     
    e199 likes this.