I am having trouble getting my Kinematic Character Controller (KCC) to ignore collisions with my sensor and I believe this is why collision events are not triggering. I tried changing the collision groups, but the character still seems to get pushed back by the sensor.
Here is how I create my controller with a collider and rigidBody:
// Create Capsule shape
let shape = new Capsule(0.25, 0.25);
// Create body/collider descriptions
let rigidBodyDesc = new RigidBodyDesc(RigidBodyType['KinematicPositionBased']);
let colliderDesc = new ColliderDesc(shape);
// Create body/collider from world
let body = world.createRigidBody(rigidBodyDesc);
let collider = world.createCollider(colliderDesc, body);
// Create Kinematic Character Controller
let controller = world.createCharacterController(0.01);
I then create the ground using similar functions:
// Create TriMesh shape
let shape = new TriMeshShape(vertices, indices, TriMeshFlags['FIX_INTERNAL_EDGES']);
let rigidBodyDesc = new RigidBodyDesc(RigidBodyType['Fixed']);
let colliderDesc = new ColliderDesc(shape);
// Create body/collider from world
let body = world.createRigidBody(rigidBodyDesc);
let collider = world.createCollider(colliderDesc, body);
Lastly, I create the sensor cube using the following code:
// Create Cuboid shape
let shape = new Cuboid(0.5, 0.5, 0.5);
// Create body/collider descriptions
let rigidBodyDesc = new RigidBodyDesc(RigidBodyType['Fixed']);
let colliderDesc = new ColliderDesc(shape).setSensor(true);
// Create body/collider from world
let body = world.createRigidBody(rigidBodyDesc);
let collider = world.createCollider(colliderDesc, body);
Assuming I get everything working, this should show collision events:
let events = new EventQueue(true);
function update() {
// Compute world
world.step(events);
// Review events
events.drainCollisionEvents(function(handle1, handle2, started) {
console.log(handle1, handle2, started);
});
}
By design, the Kinematic Character Controller will not exclude colliders with the isSensor
property set to true
. You can exclude colliders with this property by adding the parameter QueryFilterFlags['EXCLUDE_SENSORS']
with your computeColliderMovement
function.
Note: I use Vite to build my applications, so you may need to include RAPIER
before each function depending on your project. Ex: RAPIER.ActiveEvents['COLLISION_EVENTS']
// Create vectors for movement
let nextTranslation = new Vector3(0, 0, 0);
let desiredTranslation = new Vector3(0, 0, 0);
function update(delta) {
// Reset downward velocity
if (controller.computedGrounded()) desiredTranslation.y = 0;
// Simulate gravity
desiredTranslation.y -= delta;
// Compute movement and update body position
controller.computeColliderMovement(collider, desiredTranslation, QueryFilterFlags['EXCLUDE_SENSORS']);
nextTranslation.copy(body.translation());
nextTranslation.add(controller.computedMovement());
body.setNextKinematicTranslation(nextTranslation);
}
Source: github.com/dimforge/rapier.js/issues/242
The default value for all collider ActiveEvents
enum is 'NONE'
, so you will need to enable this for your KCC collider if you wish to see any collision events in the queue.
colliderDesc.setActiveEvents(ActiveEvents['COLLISION_EVENTS']);
Source: rapier.rs/docs/user_guides/javascript/colliders
Since both of your colliders are "non-dynamic", you will need to change the activeCollisionTypes
property for your KCC collider if you wish to interact with Fixed
types. The default enum value is 'DEFAULT'
, so you will need to set the active collision types to match your desired type (ex: 'KINEMATIC_FIXED'
). If you want collision events to work on all collider types, you can use 'ALL'
as your enum key.
colliderDesc.setActiveCollisionTypes(ActiveCollisionTypes['KINEMATIC_FIXED']);
Source: rapier.rs/javascript3d/enums/ActiveCollisionTypes.html
Note: My answers were written for Rapier.js v0.14.0
, so solutions may vary over time.