Search Unity

Question How to run ICollisionEventsJob on only certain collision layers

Discussion in 'Physics for ECS' started by slushieboy99, Dec 30, 2022.

  1. slushieboy99

    slushieboy99

    Joined:
    Aug 29, 2014
    Posts:
    88
    I'm trying to write a system which updates a unit when it touches the ground. I have a huge number of entities in my scene that I do not want to check, but I don't know a way to not iterate over them in an ICollisionEventJob.

    Here is my job:

    Code (CSharp):
    1. public struct UpdateGroundedTagJob : ICollisionEventsJob {
    2.     public ComponentDataFromEntity<TerrainTag> terrainTags;
    3.     public ComponentDataFromEntity<MovableComponent> movableComponents;
    4.     public ComponentDataFromEntity<GroundedTag> groundedTags;
    5.     public EntityCommandBuffer ECB;
    6.  
    7.     public void Execute(CollisionEvent collisionEvent) {
    8.         var entityA = collisionEvent.EntityA;
    9.         var entityB = collisionEvent.EntityB;
    10.  
    11.         var isBodyAGrounded = groundedTags.HasComponent(entityA);
    12.         var isBodyBGrounded = groundedTags.HasComponent(entityB);
    13.  
    14.         var isBodyATerrain = terrainTags.HasComponent(entityA);
    15.         var isBodyBTerrain = terrainTags.HasComponent(entityB);
    16.  
    17.         if (isBodyATerrain && isBodyBTerrain) {
    18.             return;
    19.         }
    20.  
    21.         var isBodyAMovable = movableComponents.HasComponent(entityA);
    22.         var isBodyBMovable = movableComponents.HasComponent(entityB);
    23.  
    24.         if ((isBodyATerrain && !isBodyBMovable) || (isBodyBTerrain && !isBodyAMovable)) {
    25.             return;
    26.         }
    27.  
    28.         var selectedUnit = isBodyATerrain ? entityB : entityA;
    29.         MovableComponent movableComponent = movableComponents[selectedUnit];
    30.         movableComponent.framesSinceGrounded = 0;
    31.         movableComponents[selectedUnit] = movableComponent;
    32.  
    33.         if (isBodyAGrounded || isBodyBGrounded) {
    34.             return;
    35.         }
    36.  
    37.         ECB.AddComponent<GroundedThisFrameTag>(selectedUnit);
    38.         ECB.AddComponent<GroundedTag>(selectedUnit);
    39.     }
    40. }
    And my code which runs the job:


    Code (CSharp):
    1. protected override void OnUpdate() {
    2.         var ecb = endFixedECBSystem.CreateCommandBuffer();
    3.        
    4.         var job1 = new UpdateGroundedTagJob {
    5.             terrainTags = GetComponentDataFromEntity<TerrainTag>(),
    6.             movableComponents = GetComponentDataFromEntity<MovableComponent>(),
    7.             groundedTags = GetComponentDataFromEntity<GroundedTag>(),
    8.             ECB = ecb,
    9.         };
    10.        
    11.         //Figure out if we can do this in parallel.
    12.         var job1Dep = job1.Schedule(stepPhysicsWorld.Simulation, JobHandle.CombineDependencies(this.Dependency, stepPhysicsWorld.FinalSimulationJobHandle));
    13.         job1Dep.Complete();
    14.  
    15.         endFixedECBSystem.AddJobHandleForProducer(job1Dep);
    16.         this.Dependency = JobHandle.CombineDependencies(job1Dep, stepPhysicsWorld.FinalSimulationJobHandle);
    17.     }
    Is there a way to make this job only iterate over entities which belong to a specific collision layer?
    Thanks!
     
  2. Arnold_2013

    Arnold_2013

    Joined:
    Nov 24, 2013
    Posts:
    286
    I don't think this is possible. But this part of the physics system really makes you write some horrible looking code. All trigger/collision response pairs will have to be iterated over to find/process the ones you are interested in.

    Someone from unity gave an example and I have not encountered anyway to do this more cleanly.

    https://forum.unity.com/threads/how-do-i-detect-collisions.1257156/
     
    vectorized-runner likes this.