A controller is a query, not a force.
This route turns Rapier's kinematic character controller into an obstacle-course experiment: desired movement goes in, collision-aware translation comes out, and grounded state, slope policy, autostep, and snap-to-ground remain inspectable.
Preparing the Rapier world, obstacle course, and capsule controller...
- physics
- -
- bodies
- -
- grounded
- -
- collisions
- -
- movement
- -
- input
- -
- controller
- -
- fps
- -
Use WASD or arrow keys. The on-screen buttons can be held to generate the same movement vector.
await RapierPhysics()create gravity worldworld.createCharacterController(0.01)create kinematic solverworld.createCollider(colliderDesc)create parentless capsulecomputeColliderMovement(...)query collision-aware motioncomputedMovement()read allowed translationcomputedGrounded()read floor stateenableAutostep(...)climb small stepsenableSnapToGround(...)stick to slopesnew RapierHelper(world)inspect collider topologyThe player is not a dynamic rigid body. It proposes a desired translation to Rapier, then applies the controller's computed translation to a parentless capsule collider and synchronizes the visible mesh.
Rapier is loading. The character controller becomes meaningful only when the world and capsule collider are live.
Based on the official Rapier character-controller example and JavaScript controller API. The CPU fallback preserves the interaction labels, but it does not claim full collision, slope, or autostep parity.