Update interaction prompt handling and UI text in multiple components

This commit is contained in:
2026-04-11 11:41:08 +02:00
parent 43e9e7baa0
commit 279084c7be
5 changed files with 110 additions and 76 deletions

View File

@@ -861,14 +861,9 @@ export class RuntimeHost {
for (const mixer of this.animationMixers.values()) {
mixer.update(dt);
}
if (this.runtimeScene !== null && this.activeController === this.firstPersonController && this.currentFirstPersonTelemetry !== null) {
if (this.sceneReady && this.runtimeScene !== null && this.currentFirstPersonTelemetry !== null) {
this.interactionSystem.updatePlayerPosition(this.currentFirstPersonTelemetry.feetPosition, this.runtimeScene, this.createInteractionDispatcher());
this.camera.getWorldDirection(this.cameraForward);
this.setInteractionPrompt(this.interactionSystem.resolveClickInteractionPrompt(this.currentFirstPersonTelemetry.eyePosition, {
x: this.cameraForward.x,
y: this.cameraForward.y,
z: this.cameraForward.z
}, this.runtimeScene));
this.setInteractionPrompt(this.resolveInteractionPrompt());
}
else {
this.setInteractionPrompt(null);
@@ -885,8 +880,11 @@ export class RuntimeHost {
this.renderer?.render(this.scene, this.camera);
};
applyTeleportPlayerAction(target) {
if (this.activeController === this.thirdPersonController) {
this.thirdPersonController.teleportTo(target.position, target.yawDegrees);
return;
}
this.firstPersonController.teleportTo(target.position, target.yawDegrees);
this.volumeAnimatedUniforms.length = 0;
}
applyToggleBrushVisibilityAction(brushId, visible) {
const mesh = this.brushMeshes.get(brushId);
@@ -954,11 +952,37 @@ export class RuntimeHost {
this.currentInteractionPrompt = prompt;
this.interactionPromptHandler?.(prompt);
}
resolveInteractionPrompt() {
if (this.runtimeScene === null ||
this.currentFirstPersonTelemetry === null ||
(this.activeController !== this.firstPersonController &&
this.activeController !== this.thirdPersonController)) {
return null;
}
this.camera.getWorldDirection(this.cameraForward);
const interactionOrigin = this.currentFirstPersonTelemetry.eyePosition;
const rayOrigin = this.activeController === this.thirdPersonController
? {
x: this.camera.position.x,
y: this.camera.position.y,
z: this.camera.position.z
}
: interactionOrigin;
return this.interactionSystem.resolveClickInteractionPrompt(interactionOrigin, rayOrigin, {
x: this.cameraForward.x,
y: this.cameraForward.y,
z: this.cameraForward.z
}, this.runtimeScene);
}
handleRuntimeClick = () => {
this.audioSystem.handleUserGesture();
if (this.runtimeScene === null || this.activeController !== this.firstPersonController || this.currentInteractionPrompt === null) {
if (!this.sceneReady ||
this.runtimeScene === null ||
(this.activeController !== this.firstPersonController &&
this.activeController !== this.thirdPersonController) ||
this.currentInteractionPrompt === null) {
return;
}
this.audioSystem.handleUserGesture();
this.interactionSystem.dispatchClickInteraction(this.currentInteractionPrompt.sourceEntityId, this.runtimeScene, this.createInteractionDispatcher());
};
handleRuntimePointerDown = () => {

View File

@@ -90,8 +90,8 @@ export class RuntimeInteractionSystem {
}
}
}
resolveClickInteractionPrompt(viewOrigin, viewDirection, runtimeScene) {
const normalizedViewDirection = normalizeVec3(viewDirection);
resolveClickInteractionPrompt(interactionOrigin, rayOrigin, rayDirection, runtimeScene) {
const normalizedViewDirection = normalizeVec3(rayDirection);
if (normalizedViewDirection === null) {
return null;
}
@@ -101,11 +101,11 @@ export class RuntimeInteractionSystem {
if (!interactable.enabled || !hasTriggerLinks(runtimeScene, interactable.entityId, "click")) {
continue;
}
const distance = distanceBetweenVec3(viewOrigin, interactable.position);
const distance = distanceBetweenVec3(interactionOrigin, interactable.position);
if (distance > interactable.radius) {
continue;
}
const hitDistance = raySphereHitDistance(viewOrigin, normalizedViewDirection, interactable.position, getInteractableTargetRadius(interactable));
const hitDistance = raySphereHitDistance(rayOrigin, normalizedViewDirection, interactable.position, getInteractableTargetRadius(interactable));
if (hitDistance === null) {
continue;
}