From 0e318e7cc7168d03c930f7633cdadf5a5c18aae2 Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Tue, 18 Nov 2025 15:27:08 -0600 Subject: [PATCH] Fix Fly Mode and Snap Turn not applying at runtime in VR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Observable subscription to Rigplatform so Fly Mode and Snap Turn settings take effect immediately when changed in the VR config panel, instead of only applying after exiting and re-entering XR. Changes to src/controllers/rigplatform.ts: - Import Observer, appConfigInstance, and AppConfigType - Add _configObserver property to track subscription - Add _subscribeToConfigChanges() method in constructor - Subscribe to onConfigChangedObservable to update flyMode and turnSnap - Add dispose() method to clean up observer and controllers - Log config changes for debugging Changes to src/menus/vrConfigPanel.ts: - Remove unused index parameter in forEach loop Root cause: Settings were only applied once at Rigplatform initialization in groundMeshObserver.ts. Config changes during VR session were saving to localStorage but not updating the running Rigplatform instance. Result: Fly Mode and Snap Turn now update in real-time when changed in VR. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/controllers/rigplatform.ts | 46 +++++++++++++++++++++++++++++++++- src/menus/vrConfigPanel.ts | 2 +- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/controllers/rigplatform.ts b/src/controllers/rigplatform.ts index 2575891..fd7e25e 100644 --- a/src/controllers/rigplatform.ts +++ b/src/controllers/rigplatform.ts @@ -1,4 +1,4 @@ -import {Angle, Mesh, Quaternion, Scene, Vector3, WebXRDefaultExperience} from "@babylonjs/core"; +import {Angle, Mesh, Observer, Quaternion, Scene, Vector3, WebXRDefaultExperience} from "@babylonjs/core"; import {RightController} from "./rightController"; import {LeftController} from "./leftController"; import log from "loglevel"; @@ -8,6 +8,8 @@ import {DefaultScene} from "../defaultScene"; import {ControllerEvent} from "./types/controllerEvent"; import {ControllerEventType} from "./types/controllerEventType"; import {controllerObservable} from "./controllers"; +import {appConfigInstance} from "../util/appConfig"; +import {AppConfigType} from "../util/appConfigType"; const RIGHT = "right"; const LEFT = "left"; @@ -34,6 +36,7 @@ export class Rigplatform { private _turnVelocity: number = 0; private _registered = false; private _yRotation: number = 0; + private _configObserver: Observer; constructor( xr: WebXRDefaultExperience, @@ -49,6 +52,26 @@ export class Rigplatform { this._fixRotation(); this._initializeControllers(); this._registerVelocityObserver(); + this._subscribeToConfigChanges(); + } + + /** + * Subscribe to config changes to update flyMode and turnSnap at runtime + */ + private _subscribeToConfigChanges(): void { + this._configObserver = appConfigInstance.onConfigChangedObservable.add((config) => { + // Update fly mode if changed + if (config.flyMode !== this._flyMode) { + this.flyMode = config.flyMode; + this._logger.debug('Fly mode updated from config:', config.flyMode); + } + + // Update turn snap if changed + if (config.turnSnap !== this.turnSnap) { + this.turnSnap = config.turnSnap; + this._logger.debug('Turn snap updated from config:', config.turnSnap); + } + }); } private _flyMode: boolean = true; @@ -215,4 +238,25 @@ export class Rigplatform { } }, -1, false, this, false); } + + /** + * Clean up resources and observers + */ + public dispose(): void { + // Remove config observer + if (this._configObserver) { + appConfigInstance.onConfigChangedObservable.remove(this._configObserver); + this._configObserver = null; + } + + // Clean up controllers + if (this._rightController) { + this._rightController = null; + } + if (this._leftController) { + this._leftController = null; + } + + this._logger.debug('Rigplatform disposed'); + } } \ No newline at end of file diff --git a/src/menus/vrConfigPanel.ts b/src/menus/vrConfigPanel.ts index bdb86eb..095ed44 100644 --- a/src/menus/vrConfigPanel.ts +++ b/src/menus/vrConfigPanel.ts @@ -374,7 +374,7 @@ export class VRConfigPanel { ]; // Create button for each snap value - snapValues.forEach((snap, index) => { + snapValues.forEach((snap) => { const isSelected = this._locationSnapEnabled && Math.abs(currentSnap - snap.value) < 0.001; const btn = Button.CreateSimpleButton(`locationSnap_${snap.value}`, snap.label);