character_controller_collisions
As the character moves along its path, it will hit grounds and obstacles before sliding or stepping on them. Knowing what collider was hit on this path, and where the hit took place, can be valuable to apply various logic (custom forces, sound effects, etc.) This is why a set of character collision events are collected during the calculation of its trajectory.
The character collision events are given in chronological order. For example, if, during the resolution of the character motion, the character hits an obstacle A, then slides against it, and then hits another obstacle B. The collision with A will be reported first, and the collision with B will be reported second.
The character collisions are stored in the KinematicCharacterControllerOutput::collisions field
after each update of the character controller:
/* Read the character controller collisions stored in the character controller’s output. */
fn read_character_controller_collisions(
character_controller_outputs: Query<&KinematicCharacterControllerOutput>,
) {
for output in character_controller_outputs.iter() {
for collision in &output.collisions {
// Do something with that collision information.
println!(
"The character hit the entity {:?} after moving by {}.",
collision.entity, collision.translation_applied
);
}
}
}
The hit field of each collision has the same form as the result of a
shape-casting: its first witness point and normal are on the obstacle, in
world-space, whereas its second witness point and normal are on the character, in its local-space.
Unless dynamic bodies are filtered-out by the character controller’s filters, they may be hit during the resolution of the character movement. If that happens, these dynamic bodies will generally not react to (i.e. not be pushed by) the character because the character controller’s offset prevents actual contacts from happening.
In these situations forces need to be applied manually to this rigid-bodies. The character controller can apply these forces for you if needed:
/* Configure the character controller when the collider is created. */
commands
.spawn(Collider::ball(0.5))
.insert(KinematicCharacterController {
// Enable the automatic application of impulses to the dynamic bodies
// hit by the character along its path.
apply_impulse_to_dynamic_bodies: true,
..default()
});
/* Configure dynamic impulses inside of a system. */
fn modify_character_controller_impulses(
mut character_controllers: Query<&mut KinematicCharacterController>,
) {
for mut character_controller in character_controllers.iter_mut() {
// Enable the automatic application of impulses to the dynamic bodies
// hit by the character along its path.
character_controller.apply_impulse_to_dynamic_bodies = true;
}
}
The mass of the character taken into account for computing these impulses is the mass of the rigid-body it is
attached to, unless KinematicCharacterController::custom_mass is set.