3
\$\begingroup\$

I am creating a game using the new Data-Oriented Tech Stack (DOTS).

I am using Entities with the PhysicsShape and PhysicsBody authoring components of the new Physics package. Some of my PhysicsShape have "Collison Response: Collide Raise Collision Events" set. Unfortunately the documentation of the new Physics system doesn't say anything about how I can detect and handle these collision events, and information on the Internet regarding this is very sparse and disorganized. How can I detect when one PhysicsShape collides with another one sending collision messages and run some code in that case?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Update: This answer was originally written based on Version 0.51 of the physics system. The documentation of version 1.0 of the physics system has a chapter on processing collision detection events that shows a solution applying some of the new idioms. That article might be more helpful than this answer.

You can do this with a JobComponentSystem which schedules a job implementing ICollisionEventsJob*. You also need to set that job as a dependency for the EndSimulationEntityCommandBufferSystem using AddJobHandleForProducer. Here is an example script:

using Unity.Burst;
using Unity.Entities;
using Unity.Jobs;
using Unity.Physics;
using Unity.Physics.Systems;
using UnityEngine;

public class CollisionSystem : JobComponentSystem {

    [BurstCompile]
    private struct CollisionJob : ICollisionEventsJob {
        public void Execute(CollisionEvent collisionEvent) {
            Debug.Log($"Collision between entities { collisionEvent.EntityA.Index } and { collisionEvent.EntityB.Index }");
        }
    }

    private BuildPhysicsWorld buildPhysicsWorldSystem;
    private StepPhysicsWorld stepPhysicsWorldSystem;
    private EndSimulationEntityCommandBufferSystem commandBufferSystem;

    protected override void OnCreate() {
        base.OnCreate();
        buildPhysicsWorldSystem = World.GetExistingSystem<BuildPhysicsWorld>();
        stepPhysicsWorldSystem = World.GetExistingSystem<StepPhysicsWorld>();
        commandBufferSystem = World.GetExistingSystem<EndSimulationEntityCommandBufferSystem>();
    }

    protected override JobHandle OnUpdate(JobHandle inputDeps) {    
        JobHandle jobHandle = new CollisionJob().Schedule(
            stepPhysicsWorldSystem.Simulation, 
            ref buildPhysicsWorldSystem.PhysicsWorld, 
            inputDeps);    
        commandBufferSystem.AddJobHandleForProducer(jobHandle);    
        return jobHandle;    
    }
}

Note that the physics system will usually generate multiple collision events on what appears to be just a single collision to the player. There is some debate about whether that's a bug or a feature.

* Yes, I am aware how useless this documentation article is right now. Hopefully it will get more useful in future versions of the documentation.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .