character_controller_filtering
It is possible to let the character controller ignore some obstacles. This is achieved by configuring the
filter argument of the KinematicCharacterController::move_shape method. This QueryFilter structure is detailed
in the scene query filters section.
If the character-controller is used to move a collider (and the rigid-body it may be attached to) that is present
in the physics scene, the filters must be used to exclude that collider (and that rigid-body) from the set of
obstacles (with QueryFilter::exclude_collider and QueryFilter::exclude_rigid_body) to prevent the character from
colliding with itself.
It is possible to let the character controller ignore some obstacles. This is achieved by configuring the following
fields of the KinematicCharacterController component:
filter_flags: to exclude whole families of obstacles (e.g. all the colliders attached to dynamic rigid-bodies).filter_groups: to filter based on the colliders collision groups.exclude_colliders: the set of entities of colliders to ignore.exclude_rigid_bodies: the set of entities of rigid-bodies whose attached colliders must all be ignored.filter_predicate: an arbitrary closure, wrapped into aControllerFilterPredicate, to filter-out colliders based on user-defined rules. It is given the entity of each collider as well as its Rapier collider (rapier::geometry::Collider). Since it is stored in a component, this closure can't borrow any system parameter.
/* Configure the character controller filters when the collider is created. */
commands
.spawn(Collider::ball(0.5))
.insert(KinematicCharacterController {
// Ignore all the sensors and all the colliders attached to dynamic rigid-bodies.
filter_flags: QueryFilterFlags::EXCLUDE_SENSORS | QueryFilterFlags::EXCLUDE_DYNAMIC,
// The character is part of the group 1 and only interacts with the group 2.
filter_groups: Some(CollisionGroups::new(Group::GROUP_1, Group::GROUP_2)),
// Ignore the collider attached to the `platform` entity.
exclude_colliders: [platform].into_iter().collect(),
// Ignore the colliders with a ball shape.
filter_predicate: Some(ControllerFilterPredicate::new(|_entity, collider| {
collider.shape().as_ball().is_none()
})),
..default()
});
When the obstacles to ignore depend on the state of your game (e.g. to let the characters walk through the doors that
are open), it is simpler to insert the ControllerIgnored marker component on these colliders from your own systems.
A collider with this component (or attached to a rigid-body with this component) is ignored by every character
controller, as well as by the wheels of the vehicle controllers,
until the component is removed:
/// A door the characters can only walk through while it is open.
#[derive(Component)]
struct Door {
open: bool,
}
/* Hide the open doors from every controller inside of a system. */
fn update_doors(mut commands: Commands, doors: Query<(Entity, &Door), Changed<Door>>) {
for (entity, door) in doors.iter() {
if door.open {
commands.entity(entity).insert(ControllerIgnored);
} else {
commands.entity(entity).remove::<ControllerIgnored>();
}
}
}
The collider moved by the character controller (and the rigid-body it may be attached to) is always excluded automatically from the set of obstacles: there is no need to exclude it manually.
It is possible to let the character controller ignore some obstacles. This can be achieved by setting the
optional arguments of the KinematicCharacterController.computeColliderMovement method:
filterFlags: to exclude whole families of obstacles (e.g. all the colliders attached to dynamic rigid-bodies).filterGroups: filter based on the colliders collision groups.filterPredicate: an arbitrary closure to filter-out colliders based on user-defined rules.
It is possible to let the character controller ignore some obstacles. This is achieved by configuring the options
argument (an R3QueryOptions, initialized by r3DefaultQueryOptions) of r3KinematicCharacterController_MoveShape.
This structure is detailed in the scene query filters section:
- The
flagsfield of itsfilterallows you to exclude whole families of obstacles (e.g. all the colliders attached to dynamic rigid-bodies withR3_QUERY_EXCLUDE_DYNAMIC). - The
use_groupsandgroupsfields of itsfilterallow you to filter based on the colliders collision groups. - The
exclude_colliderandexclude_rigid_bodyfields of itsfilterexclude one collider, and all the colliders attached to one rigid-body. - Its
predicatefield is an optional callback to filter-out colliders based on user-defined rules. It is given theuserDatafield of the options, a read-only access to the world (anR3ReadContext), and the handle of each collider, and returns a nonzero value to keep that collider as an obstacle.
If the character-controller is used to move a collider (and the rigid-body it may be attached to) that is present
in the physics scene, the filters must be used to exclude that collider (and that rigid-body) from the set of
obstacles (with the exclude_collider and exclude_rigid_body fields of the filter) to prevent the character from
colliding with itself.
It is possible to let the character controller ignore some obstacles. This is achieved by configuring the
filter argument of the KinematicCharacterController.move_shape method. This QueryFilter class is detailed in the
scene query filters section:
- Its
flags(aQueryFilterFlags, also set by constructors likeQueryFilter.exclude_dynamic()) allow you to exclude whole families of obstacles (e.g. all the colliders attached to dynamic rigid-bodies). - Its
groupsmethod allows you to filter based on the colliders collision groups. - Its
exclude_colliderandexclude_rigid_bodymethods exclude one collider, and all the colliders attached to one rigid-body. - Its
predicatemethod sets an optional callable to filter-out colliders based on user-defined rules. It is given theColliderHandleand theColliderof each potential obstacle, and returnsTrueto keep it as an obstacle.
If the character-controller is used to move a collider (and the rigid-body it may be attached to) that is present
in the physics scene, the filters must be used to exclude that collider (and that rigid-body) from the set of
obstacles (with QueryFilter.exclude_collider and QueryFilter.exclude_rigid_body) to prevent the character from
colliding with itself.