Signatur
Beschreibung
getHitTestResultsForTransientInput() gehört zum WebXR Hit Test Module und liefert die Hit-Test-Ergebnisse für transiente Eingabequellen. Das sind Eingaben, die es nur für die Dauer einer Aktion gibt, z. B. ein Finger-Tap auf dem Smartphone-Bildschirm in einer AR-Sitzung (targetRayMode === "screen"). Du kannst vorher nicht wissen, wann so eine Eingabe auftaucht, deshalb abonnierst du sie über ein Profil wie "generic-touchscreen" statt über ein konkretes XRSpace.
Der Ablauf: Mit XRSession.requestHitTestSourceForTransientInput({ profile, offsetRay }) erzeugst du eine XRTransientInputHitTestSource. In jedem Frame deiner Render-Schleife (requestAnimationFrame-Callback) rufst du dann frame.getHitTestResultsForTransientInput(source) auf. Das Ergebnis ist ein Array mit einem XRTransientInputHitTestResult pro aktiver passender Eingabequelle. Jedes Element hat eine Eigenschaft inputSource (die zugehörige XRInputSource) und ein Array results mit normalen XRHitTestResult-Objekten. Die Treffer sind nach Entfernung sortiert, der nächste kommt zuerst.
Typische Einsatzfälle sind „Tippen zum Platzieren“ oder das Verschieben virtueller Objekte auf erkannten Flächen in Augmented-Reality-Anwendungen. Die Pose eines Treffers holst du mit hitTestResult.getPose(referenceSpace).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $hitTestSource Pflicht | XRTransientInputHitTestSource | Die Hit-Test-Quelle, die zuvor mit XRSession.requestHitTestSourceForTransientInput() erzeugt wurde. Sie muss zur selben Sitzung wie der Frame gehören und darf nicht mit cancel() beendet worden sein. |
Rückgabewert
inputSource (XRInputSource) und results (Array<XRHitTestResult>, nach Entfernung sortiert). Ist gerade keine passende transiente Eingabe aktiv, ist das Array leer.Beispiele
Transiente Hit-Test-Quelle anfordern und pro Frame auswerten
const session = await navigator.xr.requestSession('immersive-ar', {
requiredFeatures: ['hit-test', 'local-floor']
});
const refSpace = await session.requestReferenceSpace('local-floor');
// Treffer für Bildschirm-Taps abonnieren
const transientSource = await session.requestHitTestSourceForTransientInput({
profile: 'generic-touchscreen'
});
const onFrame = (time, frame) => {
session.requestAnimationFrame(onFrame);
const transientResults = frame.getHitTestResultsForTransientInput(transientSource);
for (const { inputSource, results } of transientResults) {
if (results.length === 0) continue;
const pose = results[0].getPose(refSpace);
const { x, y, z } = pose.transform.position;
console.log(`${inputSource.handedness}: Treffer bei`, x.toFixed(2), y.toFixed(2), z.toFixed(2));
}
};
session.requestAnimationFrame(onFrame);
Tippen zum Platzieren (Tap-to-Place) mit select-Event
let latestHit = null;
const onFrame = (time, frame) => {
session.requestAnimationFrame(onFrame);
const hits = frame.getHitTestResultsForTransientInput(transientSource);
// Nächsten Treffer der ersten aktiven Eingabe merken
latestHit = hits[0]?.results[0]?.getPose(refSpace) ?? null;
};
session.requestAnimationFrame(onFrame);
session.addEventListener('select', () => {
if (!latestHit) return;
const { position, orientation } = latestHit.transform;
placeModel(position, orientation); // eigene Funktion, z. B. three.js-Mesh setzen
console.log('Objekt platziert');
});
Strahl versetzen und Quelle sauber beenden
const offsetSource = await session.requestHitTestSourceForTransientInput({
profile: 'generic-touchscreen',
// Strahl leicht nach unten neigen
offsetRay: new XRRay({ x: 0, y: 0, z: 0 }, { x: 0, y: -0.2, z: -1 })
});
session.addEventListener('end', () => {
offsetSource.cancel(); // Ressourcen freigeben
console.log('Hit-Test-Quelle beendet');
});
// Wichtig · Fallstricke
- Feature anfordern: Die Sitzung muss mit
'hit-test'inrequiredFeaturesoderoptionalFeaturesgestartet werden, sonst schlägtrequestHitTestSourceForTransientInput()fehl. - Nur im aktiven Frame: Wird die Methode außerhalb des
requestAnimationFrame-Callbacks aufgerufen, auf einem inaktiven Frame oder mit einer Quelle aus einer anderen Sitzung, wird eineInvalidStateError-DOMExceptionausgelöst. - Leere Ergebnisse sind normal: Ohne aktive Berührung oder ohne erkannte Fläche ist das Array bzw.
resultsleer. Prüfe also immer auf Länge oder nutze Optional Chaining. - Verzögerung: Die ersten Ergebnisse zu einem neuen Tap kommen oft erst ein paar Frames nach dem Beginn der Eingabe. Wenn du Ergebnisse im
select-Event brauchst, speichere den letzten Treffer zwischen, so wie im Beispiel. - Kompatibilität: Die Methode ist experimentell und praktisch nur in Chromium-basierten Browsern mit AR-Unterstützung verfügbar (Chrome für Android mit ARCore, Meta Quest Browser). Firefox und Safari unterstützen sie nicht. Außerdem ist ein sicherer Kontext (HTTPS) nötig. Prüfe die Unterstützung vorher, z. B. mit
navigator.xr?.isSessionSupported('immersive-ar'). - Datenschutz: Treffer verraten Informationen über die echte Umgebung. Browser können deshalb eine Nutzerzustimmung verlangen.