Start · Sprachen · JavaScript · Referenz · GamepadPose.linearAcceleration

GamepadPose.linearAcceleration

Eigenschaft

Schreibgeschützte Eigenschaft, die die lineare Beschleunigung des Controllers als <code>Float32Array</code> <code>[x, y, z]</code> in m/s² liefert – oder <code>null</code>, falls nicht verfügbar.

seit JavaScript Experimentell (Gamepad Extensions / WebVR), veralt Kategorie: webapi

Signatur

GamepadPose.linearAcceleration

Beschreibung

Die schreibgeschützte Eigenschaft linearAcceleration des GamepadPose-Interfaces gibt den aktuellen linearen Beschleunigungsvektor eines Controllers zurück. Das Ergebnis ist ein Float32Array mit drei Werten [x, y, z] in Metern pro Sekunde zum Quadrat (m/s²). Das Koordinatensystem ist dasselbe wie bei GamepadPose.position.

Auf ein GamepadPose-Objekt greifst du über die Eigenschaft Gamepad.pose zu. Diese ist nur bei Controllern mit Bewegungssensoren gefüllt, typischerweise bei VR-Motion-Controllern (z. B. HTC Vive, Oculus Touch) im Rahmen der alten WebVR-API. Ob die Hardware Beschleunigungsdaten überhaupt liefern kann, zeigt dir GamepadPose.hasAcceleration.

Nützlich ist der Wert zum Beispiel, um Schwung- oder Wurfbewegungen zu erkennen, Schläge mit einem virtuellen Schwert auszuwerten oder physikalisch glaubwürdige Effekte zu berechnen. Liefert der Sensor im aktuellen Frame keine Daten, ist der Wert null. Prüfe das deshalb immer, bevor du auf die Einträge zugreifst.

Weil die Werte nur eine Momentaufnahme sind, musst du sie in jedem Frame neu abfragen. Das geschieht meist in einer requestAnimationFrame-Schleife über navigator.getGamepads().

Rückgabewert

Typ
Float32Array | null
Beschreibung
Ein Float32Array mit drei Elementen [x, y, z] in m/s² oder null, wenn keine Beschleunigungsdaten vorliegen.

Beispiele

Beschleunigung eines VR-Controllers auslesen

const logAcceleration = () => {
  for (const pad of navigator.getGamepads()) {
    if (!pad?.pose) continue;

    const { hasAcceleration, linearAcceleration } = pad.pose;
    if (hasAcceleration && linearAcceleration) {
      const [x, y, z] = linearAcceleration;
      console.log(`${pad.id}: x=${x.toFixed(2)} y=${y.toFixed(2)} z=${z.toFixed(2)} m/s²`);
    }
  }
  requestAnimationFrame(logAcceleration);
};

window.addEventListener('gamepadconnected', () => requestAnimationFrame(logAcceleration));
OpenVR Gamepad: x=0.12 y=-9.78 z=0.05 m/s²

Schlagbewegung anhand der Beschleunigung erkennen

const SWING_THRESHOLD = 25; // m/s²

const magnitude = ([x, y, z]) => Math.hypot(x, y, z);

const detectSwing = () => {
  const [pad] = navigator.getGamepads();
  const acc = pad?.pose?.linearAcceleration;

  if (acc && magnitude(acc) > SWING_THRESHOLD) {
    console.log('Schlag erkannt!', magnitude(acc).toFixed(1), 'm/s²');
  }
  requestAnimationFrame(detectSwing);
};

requestAnimationFrame(detectSwing);
Schlag erkannt! 31.4 m/s²

Werte sicher kopieren und null behandeln

const getAcceleration = (pad) => {
  const acc = pad?.pose?.linearAcceleration;
  // Kopie anlegen, damit der Wert später noch stimmt
  return acc ? Array.from(acc) : [0, 0, 0];
};

const [pad] = navigator.getGamepads();
console.log(getAcceleration(pad));
[0, 0, 0]

// Wichtig · Fallstricke

  • Experimentell und veraltet: GamepadPose stammt aus der Gamepad-Extensions-Spezifikation und wurde zusammen mit WebVR genutzt. Unterstützung gab es praktisch nur in älteren Firefox-Versionen und teils hinter Flags. Chrome, Safari und Edge unterstützen die Eigenschaft nicht. Nutze für neue Projekte die WebXR Device API mit XRPose/XRInputSource. Dort gibt es linearVelocity, aber keine direkte Beschleunigung.
  • Der Wert kann auch dann null sein, wenn hasAcceleration true ist, etwa wenn das Tracking kurz abreißt. Prüfe den Wert deshalb immer auf null.
  • Bei manchen Implementierungen ist die Erdbeschleunigung (ca. 9,81 m/s²) im Wert enthalten. Das kann Schwellenwerte verfälschen.
  • Die Gamepad-API steht nur in einem sicheren Kontext (HTTPS) zur Verfügung. Außerdem kann sie per Permissions-Policy (gamepad) gesperrt sein.
  • Kopiere das zurückgegebene Array, wenn du die Werte über mehrere Frames hinweg brauchst.