Besides the physics simulation itself, applications often need to perform specific actions when some particular events occur inside of the physics world. For example, we might want to generate sounds when two solids collide, or open a door when a player comes close to it, detect when a projectile hits a target, etc. To allow those kinds of actions, it is possible to know when two objects start/stop colliding.
In addition, a special kind of collider, called sensors that do not generate any contacts points, but will detect when they start/stop touching another collider (be it another sensor or not). This is often useful to detect, e.g., that a player entered a specific area.
Finally it is possible to retrieve at any time the set of colliders interacting with another collider using various iterators provided by the contact and proximity graphs.
Sensors are a special type of collider that don't generate any contact.
Like regular colliders, they have to be added to the
ColliderSet, are given a geometric shape, and are attached to a rigid-body.
They are commonly used for detecting proximity, e.g., to detect when a player enters a
specific area or is close to a door.
The creation of a sensor is identical to the creation of a regular collider except that its sensor flag is set to
As presented in the next section sensors and regular colliders both generate events of different types to distinguish events due to contacts from events due to sensors.
I order to handle physics events, it is necessary to collect them using a structure implementing the
Because Rapier can be paralellized, this event handler must be
Send + Sync. One such structure provided by
pipeline::ChannelEventCollector. This event collector contains channels from the
crossbeam crate. These channels will be populated with events during each called
- Example 2D
- Example 3D
Contact and proximity events identify the involved colliders by their handle. It is possible to retrieve the handle of
the body a collider is attached to:
Proximity events are triggered when two sensors, or one collider and one sensor, transition between two different proximity statuses. There are three possible proximity statuses:
Proximity::Intersectingindicates two sensors (or one sensor and one collider) are touching/penetrating.
Proximity::WithinMarginindicates two sensors (or one sensor and one collider) are not touching but separated by a distance smaller than a small margin given to each collider by the physics pipeline.
Proximity::Disjointindicates two sensors (or one sensor and one collider) are no longer touching, and are too far apart to be closer than the sum of the
linear_predictiongiven to each collider.
One proximity event has the type
|The handle of the first collider/sensor involved in the proximity.|
|The handle of the second collider/sensor involved in the proximity.|
|The previous proximity status of the colliders/sensors.|
|The current proximity status of the colliders/sensors.|
Only status changes are reported, so
prev_status != new_status is guaranteed. On the other
hand, keep in mind that the body a collider/sensor is attached to is not required to have a smooth
motion. Thus, the transition from, e.g.,
Proximity::Disjoint is possible even if a smooth motion would have
necessarily triggered transitions from
Contact events are triggered when two colliders transition between having zero contact points and at least one. Transitioning between one to more than one contact points is not reported.
An iterator through all contact events may be retrieved by the
method of the
World. The yielded
ContactEvent enum has two variants:
ContactEvent::Started(h1, h2)to indicate the transition between 0 to at least one contact point.
ContactEvent::Stopped(h1, h2)to indicate the transition between at least one contact point to 0.
h2 identify the handles of the colliders involved in the contact.