Start · Sprachen · JavaScript · Referenz · GamepadPose.position

GamepadPose.position

Eigenschaft

Schreibgeschützte Eigenschaft, die die Position eines Gamepads (z. B. VR-Controller) als 3D-Vektor in Metern als <code>Float32Array</code> oder <code>null</code> liefert.

seit JavaScript Experimentell (WebVR-Erweiterung der Gamepad-API), Kategorie: webapi

Signatur

GamepadPose.position

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

Typ
Float32Array | null
Beschreibung
Ein 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');
}
Controller bei x=0.25 m, y=1.10 m, z=-0.40 m

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 });
#0: { x: 0.12, y: 1.05, z: -0.33 }

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);
Controller um 7.3 cm bewegt

// Wichtig · Fallstricke

  • Veraltet und experimentell: GamepadPose gehö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, mit XRInputSource.gripSpace und XRFrame.getPose().
  • Prüfe vorher immer, ob es pad.pose gibt und ob position nicht null ist. 3DoF-Geräte liefern keine Position.
  • hasPosition === true heißt nicht, dass in jedem Frame Daten vorliegen. Verliert der Sensor das Tracking, kann position kurzzeitig null sein.
  • Gamepad-Objekte sind Momentaufnahmen. Hole in jedem Frame neue Daten über navigator.getGamepads() und kopiere Werte, die du behalten willst, zum Beispiel mit Float32Array.from().
  • Die Gamepad-API braucht einen sicheren Kontext (HTTPS) und kann über die Permissions-Policy gamepad gesperrt sein.