Skip to main content

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.

warning

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 a ControllerFilterPredicate, 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>();
}
}
}
info

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 flags field of its filter allows you to exclude whole families of obstacles (e.g. all the colliders attached to dynamic rigid-bodies with R3_QUERY_EXCLUDE_DYNAMIC).
  • The use_groups and groups fields of its filter allow you to filter based on the colliders collision groups.
  • The exclude_collider and exclude_rigid_body fields of its filter exclude one collider, and all the colliders attached to one rigid-body.
  • Its predicate field is an optional callback to filter-out colliders based on user-defined rules. It is given the userData field of the options, a read-only access to the world (an R3ReadContext), and the handle of each collider, and returns a nonzero value to keep that collider as an obstacle.
warning

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 (a QueryFilterFlags, also set by constructors like QueryFilter.exclude_dynamic()) allow you to exclude whole families of obstacles (e.g. all the colliders attached to dynamic rigid-bodies).
  • Its groups method allows you to filter based on the colliders collision groups.
  • Its exclude_collider and exclude_rigid_body methods exclude one collider, and all the colliders attached to one rigid-body.
  • Its predicate method sets an optional callable to filter-out colliders based on user-defined rules. It is given the ColliderHandle and the Collider of each potential obstacle, and returns True to keep it as an obstacle.
warning

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.