Collisions & triggers
The collision system
Section titled “The collision system”createCollisionSystem(rapierWorld, eventQueue)
(packages/engine/src/physics/collision-system.ts) drains Rapier’s event queue once per
tick, in postPhysics. Register a handler:
const collisions = createCollisionSystem(rapierWorld, eventQueue);collisions.onCollision((handleA, handleB, started) => { // started === true on contact begin, false on contact end});// each postPhysics: collisions.drain();A handler receives the two collider handles and a started boolean. Events are
buffered first, then handlers run after the drain — so it’s safe to create/destroy bodies
inside a handler without corrupting Rapier’s iteration. Resolve a handle back to its entity
with physics.getByColliderHandle(handle) (see the registry).
Triggers
Section titled “Triggers”createTriggerDispatch(...) (packages/engine/src/physics/trigger-dispatch.ts) builds a
collision handler that turns sensor overlaps into component callbacks. It is registered
once via collisions.onCollision(createTriggerDispatch(...)). For each sensor-involved
overlap it resolves both collider handles to their Object3Ds and calls, on each side’s
GameComponents:
onTriggerEnter(other, ctx)whenstartedis true;onTriggerExit(other, ctx)whenstartedis false.
other is the other entity’s Object3D. Only sensor-involved overlaps dispatch
triggers — solid-vs-solid contacts are ordinary collisions, not triggers.
See also
Section titled “See also”- Colliders —
isSensorand collision layers. - Entities & components — where the trigger callbacks live.
- Rigid bodies — the registry that resolves handles to entities.