Signatur
Beschreibung
Die Eigenschaft position des Interfaces GamepadPose gibt die aktuelle Position eines ortsbezogen erfassten Controllers als dreielementiges Float32Array [x, y, z] zurück. Du erreichst das GamepadPose-Objekt über Gamepad.pose. Das betrifft vor allem VR-Controller mit 6DoF-Tracking, also mit drei Achsen für Drehung und drei für Position.
Die Werte sind in Metern angegeben. Das Koordinatensystem ist rechtshändig: +X zeigt nach rechts, +Y nach oben und -Z nach vorn. Der Ursprung ist die Stelle, an der der Sensor den Controller zum ersten Mal erfasst hat, oder eine festgelegte Sitzposition.
Kann das Gerät keine Position melden, ist der Wert null. Das gilt zum Beispiel für 3DoF-Controller, die nur die Ausrichtung erfassen. Ob Positionsdaten grundsätzlich möglich sind, zeigt GamepadPose.hasPosition. Weil die Daten nur einen Moment abbilden, liest man sie meist bei jedem Frame in einer requestAnimationFrame-Schleife neu aus navigator.getGamepads() aus.
Rückgabewert
Float32Array mit drei Werten [x, y, z] in Metern oder null, wenn keine Positionsdaten verfügbar sind.Beispiele
Position eines Controllers einmalig auslesen
const [pad] = navigator.getGamepads().filter(Boolean);
if (pad?.pose?.hasPosition && pad.pose.position) {
const [x, y, z] = pad.pose.position;
console.log(`Controller bei x=${x.toFixed(2)} m, y=${y.toFixed(2)} m, z=${z.toFixed(2)} m`);
} else {
console.log('Keine Positionsdaten verfügbar');
}
Position in jedem Frame verfolgen
const trackControllers = () => {
for (const pad of navigator.getGamepads()) {
const pos = pad?.pose?.position;
if (!pos) continue;
// Werte kopieren, da das Array beim nächsten Abruf ersetzt wird
const [x, y, z] = Array.from(pos);
console.log(`#${pad.index}:`, { x, y, z });
}
requestAnimationFrame(trackControllers);
};
window.addEventListener('gamepadconnected', () => requestAnimationFrame(trackControllers), { once: true });
Bewegte Strecke zwischen zwei Messungen berechnen
let last = null;
const measure = () => {
const pos = navigator.getGamepads()[0]?.pose?.position;
if (pos) {
if (last) {
const d = Math.hypot(pos[0] - last[0], pos[1] - last[1], pos[2] - last[2]);
if (d > 0.05) console.log(`Controller um ${(d * 100).toFixed(1)} cm bewegt`);
}
last = Float32Array.from(pos);
}
requestAnimationFrame(measure);
};
requestAnimationFrame(measure);
// Wichtig · Fallstricke
- Veraltet und experimentell:
GamepadPosegehört zur abgelösten WebVR-Erweiterung. Nur wenige Browser haben die Schnittstelle umgesetzt, etwa ältere Firefox-Versionen, teils nur hinter einem Flag. Für neue Projekte ist die WebXR Device API gedacht, mitXRInputSource.gripSpaceundXRFrame.getPose(). - Prüfe vorher immer, ob es
pad.posegibt und obpositionnichtnullist. 3DoF-Geräte liefern keine Position. hasPosition === trueheißt nicht, dass in jedem Frame Daten vorliegen. Verliert der Sensor das Tracking, kannpositionkurzzeitignullsein.- Gamepad-Objekte sind Momentaufnahmen. Hole in jedem Frame neue Daten über
navigator.getGamepads()und kopiere Werte, die du behalten willst, zum Beispiel mitFloat32Array.from(). - Die Gamepad-API braucht einen sicheren Kontext (HTTPS) und kann über die Permissions-Policy
gamepadgesperrt sein.