Signatur
Beschreibung
Die Eigenschaft removed des XRInputSourcesChangeEvent enthält alle Eingabequellen, etwa Controller, Hände (Hand-Tracking) oder Blick-/Tipp-Eingaben, die der XRSession nicht mehr zur Verfügung stehen. Das passiert zum Beispiel, wenn ein Controller ausgeschaltet oder abgelegt wird, der Akku leer ist oder das System vom Controller auf Hand-Tracking umschaltet.
Ausgelöst wird das Ereignis inputsourceschange an der XRSession. In einem Ereignis können gleichzeitig Quellen hinzukommen (added) und wegfallen (removed). Deshalb sollte man immer beide Arrays auswerten. Das Array kann auch leer sein.
Typischerweise nutzt man removed, um zu jeder Eingabequelle gespeicherte Daten aufzuräumen. Dazu gehören 3D-Modelle des Controllers, Laserstrahlen, Zuordnungen zu Spielerhänden oder Haptik-Zustände. Die entfernten XRInputSource-Objekte sind dieselben Objektreferenzen, die vorher in added bzw. in session.inputSources standen. Deshalb eignen sie sich gut als Schlüssel in einer Map oder WeakMap.
Rückgabewert
FrozenArray) mit null oder mehr XRInputSource-Objekten, die aus der Session entfernt wurden.Beispiele
Entfernte Controller protokollieren
const session = await navigator.xr.requestSession('immersive-vr');
session.addEventListener('inputsourceschange', (event) => {
for (const source of event.removed) {
console.log(`Entfernt: ${source.handedness} (${source.targetRayMode})`, source.profiles);
}
});
Controller-Modelle beim Entfernen aufräumen
// Zuordnung Eingabequelle -> 3D-Objekt der Szene
const controllerModels = new Map();
const onInputSourcesChange = ({ added, removed }) => {
for (const source of removed) {
const model = controllerModels.get(source);
if (model) {
model.removeFromParent?.(); // z. B. three.js-Objekt aus der Szene nehmen
controllerModels.delete(source);
}
}
for (const source of added) {
if (source.targetRayMode === 'tracked-pointer') {
controllerModels.set(source, { name: `controller-${source.handedness}` });
}
}
console.log('Aktive Controller:', controllerModels.size);
};
const session = await navigator.xr.requestSession('immersive-vr');
session.addEventListener('inputsourceschange', onInputSourcesChange);
Wechsel von Controller zu Hand-Tracking erkennen
const session = await navigator.xr.requestSession('immersive-vr', {
optionalFeatures: ['hand-tracking']
});
session.oninputsourceschange = (event) => {
const lostControllers = event.removed.filter((s) => !s.hand);
const newHands = event.added.filter((s) => s.hand);
if (lostControllers.length && newHands.length) {
console.log('Nutzer hat auf Hand-Tracking gewechselt');
}
};
// Wichtig · Fallstricke
- Schreibgeschützt und eingefroren: Das Array kann nicht verändert werden.
push()odersplice()werfen im Strict Mode einenTypeError. Wer das Array bearbeiten möchte, kopiert es vorher mit[...event.removed]. - Beide Arrays prüfen: Ein einzelnes Ereignis kann sowohl
addedals auchremovedbefüllen, etwa beim Wechsel vom Controller zur Hand. Wer nur eines davon auswertet, übersieht Änderungen. - Keine Posen mehr abfragen: Für entfernte Quellen liefert
frame.getPose(source.targetRaySpace, refSpace)keine sinnvollen Daten mehr. Entfernte Quellen sollten daher sofort aus Render-Schleifen und Haptik-Logik genommen werden. - Beim Sitzungsende kein Ereignis: Wenn die Session endet, wird für die verbleibenden Quellen nicht zuverlässig ein
removedgemeldet. Das Aufräumen sollte deshalb zusätzlich imend-Ereignis derXRSessionstattfinden. - Kompatibilität: WebXR wird nur in sicheren Kontexten (HTTPS) unterstützt, hauptsächlich in Chromium-Browsern und im Meta Quest Browser. Firefox und Safari (Desktop) unterstützen es nicht. Zum Testen am Desktop eignet sich der WebXR-API-Emulator.