Signatur
Beschreibung
GamepadPose.linearVelocity gibt an, wie schnell und in welche Richtung sich ein getrackter Controller, etwa ein VR-Motion-Controller, gerade im Raum bewegt. Der Wert ist ein Float32Array mit drei Elementen [x, y, z]. Jedes Element steht für die Geschwindigkeit entlang der jeweiligen Achse in Metern pro Sekunde. Wie bei WebVR üblich zeigt die x-Achse nach rechts, die y-Achse nach oben und die negative z-Achse nach vorn.
An das GamepadPose-Objekt kommt man über die Eigenschaft pose eines Gamepad-Objekts, zum Beispiel navigator.getGamepads()[0].pose. Die Geschwindigkeit ist nützlich für physikbasierte Interaktionen. Ein typischer Fall ist das Werfen eines virtuellen Objekts: Beim Loslassen übernimmt das Objekt die aktuelle Geschwindigkeit der Hand. Außerdem lässt sich damit die Position vorausberechnen, um Latenz auszugleichen.
Kann das Gerät keine lineare Geschwindigkeit melden, ist der Wert null. Ob das der Fall ist, zeigt die Eigenschaft GamepadPose.hasPosition. Der Wert ist eine Momentaufnahme. Deshalb sollte man ihn in jedem Frame neu auslesen, am besten innerhalb von requestAnimationFrame.
Rückgabewert
Float32Array mit drei Werten [x, y, z] in m/s oder null, wenn das Gerät keine Geschwindigkeitsdaten liefert.Beispiele
Geschwindigkeit eines Controllers auslesen (mit Prüfung, ob die API vorhanden ist)
const logVelocity = () => {
const pads = navigator.getGamepads?.() ?? [];
for (const pad of pads) {
// pose gibt es nur, wenn die Gamepad-Erweiterung unterstützt wird
const velocity = pad?.pose?.linearVelocity;
if (!velocity) continue;
const [x, y, z] = velocity;
console.log(`${pad.id}: x=${x.toFixed(2)} y=${y.toFixed(2)} z=${z.toFixed(2)} m/s`);
}
};
window.addEventListener('gamepadconnected', () => logVelocity());
Geschwindigkeit als Betrag in jedem Frame berechnen
const speedOf = (v) => Math.hypot(v[0], v[1], v[2]);
const loop = () => {
const pad = navigator.getGamepads?.()[0];
const v = pad?.pose?.linearVelocity;
if (v) {
const speed = speedOf(v);
if (speed > 3) console.log(`Schnelle Bewegung: ${speed.toFixed(1)} m/s`);
}
requestAnimationFrame(loop);
};
requestAnimationFrame(loop);
Wurfgeschwindigkeit beim Loslassen übernehmen
const ball = { position: [0, 1, 0], velocity: [0, 0, 0] };
let wasPressed = false;
const update = () => {
const pad = navigator.getGamepads?.()[0];
if (pad?.pose) {
const pressed = pad.buttons[0]?.pressed ?? false;
// Trigger losgelassen: Ball bekommt die Handgeschwindigkeit
if (wasPressed && !pressed && pad.pose.linearVelocity) {
ball.velocity = Array.from(pad.pose.linearVelocity);
console.log('Wurf mit', ball.velocity);
}
wasPressed = pressed;
}
requestAnimationFrame(update);
};
requestAnimationFrame(update);
// Wichtig · Fallstricke
- Veraltet und experimentell:
GamepadPosegehört zur WebVR-Gamepad-Erweiterung. Diese war nur in einzelnen Browsern verfügbar, etwa in Firefox mitdom.gamepad.extensions.enabledoder in Chrome mit WebVR-Flags, und wurde inzwischen weitgehend entfernt. Für neue Projekte ist die WebXR Device API gedacht, dort mitXRPose.linearVelocity. - Immer auf
nullprüfen: Sowohlgamepad.poseals auchlinearVelocitykönnennulloderundefinedsein. Optionales Verketten (?.) schützt vor Laufzeitfehlern. - Momentaufnahme: In Chrome sind
Gamepad-Objekte Momentaufnahmen. Man solltenavigator.getGamepads()deshalb in jedem Frame neu aufrufen, statt eine alte Referenz aufzubewahren. - Das zurückgegebene
Float32Arraykann bei der nächsten Aktualisierung wiederverwendet werden. Wer die Werte speichern will, sollte sie kopieren, zum Beispiel mitArray.from(). - Die Gamepad-API steht nur in einem sicheren Kontext (HTTPS) zur Verfügung und kann durch eine Permissions-Policy (
gamepad) gesperrt sein.