You can fix this by adding the CollisionGroups component to the entity as well as setting the filter_groups feild inside of the KinematicCharacterController.
Overview
The KinematicCharacterController collision groups filters are not working as expected. If we assign CollisionGroups::new(Group::GROUP_1, Group::GROUP_2) to two character controllers we would not expect them to collide as per the docs:
An interaction is allowed between two filters a and b when two conditions are met simultaneously:
The groups membership of a has at least one bit set to 1 in common with the groups filter of b.
The groups membership of b has at least one bit set to 1 in common with the groups filter of a.
In other words, interactions are allowed between two filter iff. the following condition is met:
(self.memberships & rhs.filter) != 0 && (rhs.memberships & self.filter) != 0
However, they do collide.
Investigation
The correct QueryFilter is being sent to the KinematicCharacterController::move_shape method so, from my testing, the problem lies in there.
Example
[WASD] to move
use bevy::prelude::*;
use bevy_rapier3d::prelude::*;
Edit
You can fix this by adding the
CollisionGroups
component to the entity as well as setting thefilter_groups
feild inside of theKinematicCharacterController
.Overview
The
KinematicCharacterController
collision groups filters are not working as expected. If we assignCollisionGroups::new(Group::GROUP_1, Group::GROUP_2)
to two character controllers we would not expect them to collide as per the docs:However, they do collide.
Investigation
The correct
QueryFilter
is being sent to theKinematicCharacterController::move_shape
method so, from my testing, the problem lies in there.Example
[derive(Clone, Bundle)]
pub struct KinematicColliderBundle { pub kinematic: KinematicCharacterController, pub collider: Collider, pub collider_scale: ColliderScale, pub velocity: Velocity, pub locked_axes: LockedAxes, pub ccd: Ccd, }
impl Default for KinematicColliderBundle { fn default() -> Self { Self { kinematic: KinematicCharacterController { up: Vec3::Y, autostep: Some(CharacterAutostep { max_height: CharacterLength::Absolute(0.05), min_width: CharacterLength::Absolute(0.05), include_dynamic_bodies: false, }), ..default() }, collider: Collider::cuboid(1., 1., 1.), collider_scale: ColliderScale::Absolute(Vec3::new(1., 1., 1.)), velocity: Velocity::zero(), locked_axes: LockedAxes::ROTATION_LOCKED | LockedAxes::TRANSLATION_LOCKED_Z, ccd: Ccd::enabled(), } } }
fn main() { App::new() .insert_resource(ClearColor(Color::rgb( 0xF9 as f32 / 255.0, 0xF9 as f32 / 255.0, 0xFF as f32 / 255.0, ))) .add_plugins(DefaultPlugins) .add_plugin(RapierPhysicsPlugin::::default())
.add_plugin(RapierDebugRenderPlugin::default())
.add_startup_system(setup_graphics)
.add_startup_system(setup_physics)
.add_system(input)
.run();
}
fn setup_graphics(mut commands: Commands) { commands.spawn(Camera3dBundle { transform: Transform::from_xyz(0.0, 0.0, -30.0) .looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y), ..Default::default() }); }
[derive(Component)]
struct Controlled;
fn input( mut q_player: Query<&mut KinematicCharacterController, With>,
keyboard_input: Res<Input>,
) {
let mut player = q_player.single_mut();
}
pub fn setup_physics(mut commands: Commands) { let group = Some(CollisionGroups::new(Group::GROUP_1, Group::GROUP_2));
}