THREE.JS / FOUNDATIONS 203

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.

Initializing Preparing renderer

Preparing the Rapier world, obstacle course, and capsule controller...

physics
-
bodies
-
grounded
-
collisions
-
movement
-
input
-
controller
-
fps
-
Character controlscapsule

Use WASD or arrow keys. The on-screen buttons can be held to generate the same movement vector.

Character controller contractofficial API boundary
await RapierPhysics()create gravity world
world.createCharacterController(0.01)create kinematic solver
world.createCollider(colliderDesc)create parentless capsule
computeColliderMovement(...)query collision-aware motion
computedMovement()read allowed translation
computedGrounded()read floor state
enableAutostep(...)climb small steps
enableSnapToGround(...)stick to slopes
new RapierHelper(world)inspect collider topology

The 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.

Controller telemetryno contact
position-
computed movement-
last normal-
settings-

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.

THREE.JS FOUNDATIONS LAB