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. Join us on March 30, 2023, between 5 am & 1 pm EST, in the Performance Profiling Dev Blitz Day 2023 - Q&A forum and Discord where you can connect with our teams behind the Memory and CPU Profilers.
    Dismiss Notice

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:
    65
    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:
    190
    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.