using System.Collections; using UnityEngine; using UnityEngine.XR; using UnityEngine.XR.Management; using UnityEngine.XR.OpenXR; namespace BlockSpace.Voxels { internal static class OpenXRDesktopFallback { private sealed class OpenXRDesktopFallbackRunner : MonoBehaviour { private bool started; private IEnumerator Start() { if (started) { yield break; } started = true; float waitTime = 2f; float timer = 0f; while (timer < waitTime) { if (XRSettings.isDeviceActive) { Debug.Log("XR already active. Skipping fallback."); yield break; } timer += Time.unscaledDeltaTime; yield return null; } XRGeneralSettings instance = XRGeneralSettings.Instance; XRManagerSettings manager = ((instance != null) ? instance.Manager : null); if (manager == null) { Debug.LogWarning("No XR Manager found. Staying in desktop mode."); yield break; } if (manager.activeLoader != null || XRSettings.isDeviceActive) { Debug.Log("XR initialized during wait. No fallback needed."); yield break; } Debug.Log("XR not initialized. Attempting manual initialization..."); yield return manager.InitializeLoader(); if (manager.activeLoader != null) { manager.StartSubsystems(); if (XRSettings.isDeviceActive) { Debug.Log("XR successfully initialized via fallback."); } else { Debug.LogWarning("Loader started but no XR device active."); } } else { Debug.Log("OpenXR failed to initialize. Running in desktop mode."); } } } private static bool installed; private static bool runnerCreated; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void Install() { if (!installed) { installed = true; OpenXRRuntime.retryInitializationOnFormFactorErrors = false; OpenXRRuntime.wantsToQuit += PreventForcedQuit; OpenXRRuntime.wantsToRestart += PreventForcedRestart; } } [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] private static void CreateRunner() { if (!runnerCreated) { runnerCreated = true; GameObject gameObject = new GameObject("OpenXRDesktopFallback"); Object.DontDestroyOnLoad(gameObject); gameObject.hideFlags = HideFlags.HideAndDontSave; gameObject.AddComponent(); } } private static bool PreventForcedQuit() { Debug.LogWarning("OpenXR requested application quit. Ignoring for desktop fallback."); return false; } private static bool PreventForcedRestart() { Debug.LogWarning("OpenXR requested restart. Ignoring for desktop fallback."); return false; } } }