Input and movement
Controllers, hands, and the uncomfortable problem of moving someone through a space they are standing still in.
Input in XR is not events. There is no click, no keydown, no element under the pointer. On every frame you are handed a set of input sources, each with a pose, a gamepad-like button state, and possibly a 25-joint hand skeleton — and it is your job to decide what any of that means. A pinch, a grab, a pointer ray, a teleport arc: none of them exist in the API. You build them from poses.
The three pages here go from the concrete to the contested. Controllers is the most mechanical: input sources, the targetRay versus grip distinction that trips up almost everyone once, button and axis state, and haptics. Hand tracking replaces the buttons with geometry — the same input model, but now a gesture is a distance between two joints and a threshold you picked. Locomotion is the one with no correct answer, because the constraint is not technical.
That last page is the reason this section exists as a group rather than three unrelated topics. Every input decision in XR eventually runs into the body: a ray is easier to aim than a hand but less direct, a pinch threshold that feels crisp to you registers as a missed grab for someone else, and smooth locomotion that looks best in a video is the one that sends a portion of your users to sit down. The API gives you poses. Comfort is a design problem you cannot read off the spec.
In this section
- VR controllersA controller reaches your code as an XRInputSource: two separate spaces, an optional gamepad, and a select event that works the same on every device — including the ones with no controller at all.
- Hand trackingA tracked hand arrives as an XRHand: a map of 25 named joints, each with its own pose, orientation and radius — and each one allowed to be missing on any given frame.
- Locomotion and comfortYou never move the camera in WebXR. You replace the reference space with an offset copy of itself — and the difference between doing that instantly and doing it gradually is the difference between a comfortable app and a nauseating one.
Read these in order
Controllers establishes the input-source model — how a frame hands you devices, poses and button state. Hand tracking assumes you already have that model and swaps in a skeleton.
Locomotion comes last on purpose. It is the page that depends on both of the others and on a judgement call neither of them requires: how much movement you are willing to impose on someone who is not actually moving.