Signatur
Beschreibung
Die Eigenschaft Gamepad.pose gehört zu den Erweiterungen, die die WebVR-API dem Gamepad-Interface hinzufügt. Sie gibt ein GamepadPose-Objekt zurück, das den aktuellen räumlichen Zustand eines VR-Controllers beschreibt, zum Beispiel eines Oculus-Touch- oder HTC-Vive-Controllers. Bei klassischen Gamepads ohne Positionsverfolgung ist der Wert null.
Das GamepadPose-Objekt stellt unter anderem diese Werte bereit:
hasPosition/hasOrientation: Wahrheitswerte, die angeben, ob das Gerät Position bzw. Ausrichtung überhaupt melden kann.position:Float32Arraymit[x, y, z]in Metern odernull.orientation: Quaternion[x, y, z, w]alsFloat32Arrayodernull.linearVelocity,linearAcceleration,angularVelocity,angularAcceleration: Bewegungsdaten, jeweilsFloat32Arrayodernull.
Die Pose wird wie alle Gamepad-Daten als Momentaufnahme geliefert. Du musst deshalb in jedem Frame (typischerweise in requestAnimationFrame bzw. VRDisplay.requestAnimationFrame) über navigator.getGamepads() neu abfragen, um aktuelle Werte zu bekommen.
Die WebVR-API ist veraltet und wurde durch die WebXR Device API ersetzt. Für neue Projekte solltest du Controller-Posen über XRInputSource.gripSpace bzw. targetRaySpace und XRFrame.getPose() ermitteln.
Rückgabewert
GamepadPose-Objekt mit den aktuellen Pose-Daten des Controllers oder null, wenn das Gerät keine Pose-Informationen liefert.Beispiele
Pose eines VR-Controllers pro Frame auslesen
const formatVec = (arr) => arr ? Array.from(arr, (v) => v.toFixed(2)).join(', ') : 'n/a';
const update = () => {
for (const pad of navigator.getGamepads()) {
// Nur Controller mit Pose-Unterstützung berücksichtigen
if (!pad || !('pose' in pad) || !pad.pose) continue;
const { pose } = pad;
if (pose.hasPosition) {
console.log(`${pad.id} Position: ${formatVec(pose.position)}`);
}
if (pose.hasOrientation) {
console.log(`${pad.id} Ausrichtung: ${formatVec(pose.orientation)}`);
}
}
requestAnimationFrame(update);
};
window.addEventListener('gamepadconnected', () => requestAnimationFrame(update), { once: true });
Feature-Erkennung: Gamepad mit oder ohne Pose
window.addEventListener('gamepadconnected', (event) => {
const pad = event.gamepad;
const supportsPose = 'pose' in pad && pad.pose !== null;
console.log(`${pad.id}: ${supportsPose ? 'VR-Controller mit Pose' : 'klassisches Gamepad'}`);
if (supportsPose) {
console.log('Hand:', pad.hand || 'unbekannt');
}
});
Moderne Alternative: Controller-Pose mit WebXR
const startXR = async () => {
if (!navigator.xr || !(await navigator.xr.isSessionSupported('immersive-vr'))) {
console.log('WebXR VR wird nicht unterstützt');
return;
}
const session = await navigator.xr.requestSession('immersive-vr');
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl', { xrCompatible: true });
await session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });
const refSpace = await session.requestReferenceSpace('local');
const onFrame = (time, frame) => {
for (const source of session.inputSources) {
if (!source.gripSpace) continue;
const pose = frame.getPose(source.gripSpace, refSpace);
if (pose) {
const { x, y, z } = pose.transform.position;
console.log(`${source.handedness}: ${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`);
}
}
session.requestAnimationFrame(onFrame);
};
session.requestAnimationFrame(onFrame);
};
// Muss durch eine Nutzeraktion ausgelöst werden
document.querySelector('#vr-button').addEventListener('click', startXR);
// Wichtig · Fallstricke
- Veraltet und experimentell:
Gamepad.posegehört zur eingestellten WebVR-API. Chrome hat sie nie standardmäßig ausgeliefert, Firefox hat WebVR entfernt bzw. nur noch hinter Flags. Verwende für neue Projekte die WebXR Device API. - Prüfe immer mit
'pose' in gamepadund aufnull, bevor du darauf zugreifst. Einzelne Felder wiepositionkönnen trotz vorhandenem Objektnullsein, deshalb zusätzlichhasPosition/hasOrientationauswerten. - Die Werte sind Momentaufnahmen: Ein einmal gespeichertes
Gamepad-Objekt wird in Chromium-basierten Browsern nicht aktualisiert, frag deshalb in jedem Frame neu übernavigator.getGamepads()ab. - Positionen sind in Metern relativ zum Tracking-Ursprung angegeben, die Ausrichtung als Quaternion
[x, y, z, w], nicht als Euler-Winkel. - Die Gamepad-API gibt es nur in sicheren Kontexten (HTTPS). Außerdem kann sie per Permissions-Policy
gamepadgesperrt sein.