From 52d4ef3279a289ed29a3a21aba97445a66182447 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 20 Jun 2023 06:05:51 -0500 Subject: [PATCH] [DesktopVRSwitch] Wait frame on MovementSystem OnPostSwitch. testing --- DesktopVRSwitch/HarmonyPatches.cs | 6 +- DesktopVRSwitch/Main.cs | 2 +- DesktopVRSwitch/Utils.cs | 16 +++-- DesktopVRSwitch/VRModeSwitchDebugger.cs | 39 +++++++++++ DesktopVRSwitch/VRModeSwitchManager.cs | 30 ++++---- .../VRModeTrackers/MetaPortTracker.cs | 8 +-- .../VRModeTrackers/MovementSystemTracker.cs | 68 ++++++++++++++----- .../VRModeTrackers/PlayerSetupTracker.cs | 2 +- 8 files changed, 123 insertions(+), 48 deletions(-) create mode 100644 DesktopVRSwitch/VRModeSwitchDebugger.cs diff --git a/DesktopVRSwitch/HarmonyPatches.cs b/DesktopVRSwitch/HarmonyPatches.cs index 462a3f3..e8bd48f 100644 --- a/DesktopVRSwitch/HarmonyPatches.cs +++ b/DesktopVRSwitch/HarmonyPatches.cs @@ -3,11 +3,11 @@ using ABI_RC.Core.Savior; using ABI_RC.Core.Util.Object_Behaviour; using ABI_RC.Systems.IK; using ABI_RC.Systems.IK.TrackingModules; +using cohtml; using HarmonyLib; using NAK.DesktopVRSwitch.Patches; using NAK.DesktopVRSwitch.VRModeTrackers; using UnityEngine; -using cohtml; namespace NAK.DesktopVRSwitch.HarmonyPatches; @@ -75,9 +75,9 @@ class CVRPickupObjectPatches [HarmonyPatch(typeof(CVRPickupObject), nameof(CVRPickupObject.Start))] static void Prefix_CVRPickupObject_Start(ref CVRPickupObject __instance) { - if (__instance.gripType == CVRPickupObject.GripType.Free) + if (__instance.gripType == CVRPickupObject.GripType.Free) return; - + Transform vrOrigin = __instance.gripOrigin; Transform desktopOrigin = __instance.gripOrigin.Find("[Desktop]"); if (vrOrigin != null && desktopOrigin != null) diff --git a/DesktopVRSwitch/Main.cs b/DesktopVRSwitch/Main.cs index 04bedbf..d098656 100644 --- a/DesktopVRSwitch/Main.cs +++ b/DesktopVRSwitch/Main.cs @@ -58,7 +58,7 @@ public class DesktopVRSwitch : MelonMod { if (Input.GetKeyDown(KeyCode.F6) && Input.GetKey(KeyCode.LeftControl)) { - VRModeSwitchManager.Instance?.StartSwitch(); + VRModeSwitchManager.Instance?.AttemptSwitch(); } } diff --git a/DesktopVRSwitch/Utils.cs b/DesktopVRSwitch/Utils.cs index 6743a39..02c363c 100644 --- a/DesktopVRSwitch/Utils.cs +++ b/DesktopVRSwitch/Utils.cs @@ -1,7 +1,6 @@ using ABI_RC.Core.EventSystem; using ABI_RC.Core.Player; using ABI_RC.Core.Savior; -using ABI_RC.Systems.MovementSystem; using UnityEngine; namespace NAK.DesktopVRSwitch; @@ -17,13 +16,10 @@ internal static class Utils return PlayerSetup.Instance.desktopCamera; } - //stole from kafe :> - internal static Vector3 GetPlayerRootPosition() + internal static void ClearLocalAvatar() { - return MovementSystem.Instance.rotationPivot.position with - { - y = MovementSystem.Instance.transform.position.y - }; + DesktopVRSwitch.Logger.Msg("Clearing local avatar."); + PlayerSetup.Instance.ClearAvatar(); } internal static void ReloadLocalAvatar() @@ -31,4 +27,10 @@ internal static class Utils DesktopVRSwitch.Logger.Msg("Attempting to reload current local avatar from GUID."); AssetManagement.Instance.LoadLocalAvatar(MetaPort.Instance.currentAvatarGuid); } + + internal static bool IsLocalAvatarLoaded() + { + return PlayerSetup.Instance._avatar != null; + } + } diff --git a/DesktopVRSwitch/VRModeSwitchDebugger.cs b/DesktopVRSwitch/VRModeSwitchDebugger.cs new file mode 100644 index 0000000..72383b0 --- /dev/null +++ b/DesktopVRSwitch/VRModeSwitchDebugger.cs @@ -0,0 +1,39 @@ +using System.Collections; +using UnityEngine; + +namespace NAK.DesktopVRSwitch; + +class VRModeSwitchDebugger : MonoBehaviour +{ + private Coroutine _switchCoroutine; + private WaitForSeconds _sleep = new WaitForSeconds(2.5f); + + private void OnEnable() + { + if (_switchCoroutine == null) + _switchCoroutine = StartCoroutine(SwitchLoop()); + } + + private void OnDisable() + { + if (_switchCoroutine != null) + { + StopCoroutine(_switchCoroutine); + _switchCoroutine = null; + } + } + + private IEnumerator SwitchLoop() + { + while (true) + { + if (!VRModeSwitchManager.Instance.SwitchInProgress) + { + VRModeSwitchManager.Instance.AttemptSwitch(); + yield return _sleep; + } + + yield return null; + } + } +} diff --git a/DesktopVRSwitch/VRModeSwitchManager.cs b/DesktopVRSwitch/VRModeSwitchManager.cs index a82d147..aa25ff1 100644 --- a/DesktopVRSwitch/VRModeSwitchManager.cs +++ b/DesktopVRSwitch/VRModeSwitchManager.cs @@ -44,11 +44,11 @@ public class VRModeSwitchManager : MonoBehaviour } // Settings - private bool _useWorldTransition = true; - private bool _reloadLocalAvatar = true; + public bool _useWorldTransition = true; + public bool _reloadLocalAvatar = true; - // Internal - private bool _switchInProgress = false; + // Info + public bool SwitchInProgress { get; private set; } void Awake() { @@ -60,18 +60,18 @@ public class VRModeSwitchManager : MonoBehaviour Instance = this; } - public void StartSwitch() + public void AttemptSwitch() { StartCoroutine(StartSwitchCoroutine()); } private IEnumerator StartSwitchCoroutine() { - if (_switchInProgress) + if (SwitchInProgress) { yield break; } - _switchInProgress = true; + SwitchInProgress = true; yield return null; @@ -96,12 +96,14 @@ public class VRModeSwitchManager : MonoBehaviour // Check for updated VR mode if (isUsingVr != IsInVR()) { - InvokeOnPostSwitch(!isUsingVr); - // reload the local avatar - // only reload on success if (_reloadLocalAvatar) + { + Utils.ClearLocalAvatar(); Utils.ReloadLocalAvatar(); + } + + InvokeOnPostSwitch(!isUsingVr); } else { @@ -111,7 +113,7 @@ public class VRModeSwitchManager : MonoBehaviour if (_useWorldTransition) // finish the visual transition and wait yield return WorldTransitionSystem.Instance.ContinueTransitionCoroutine(); - _switchInProgress = false; + SwitchInProgress = false; yield break; } @@ -166,14 +168,14 @@ public class VRModeSwitchManager : MonoBehaviour SteamVR_ActionSet_Manager.DisableAllActionSets(); SteamVR_Input.initialized = false; - // Remove SteamVR + // Remove SteamVR behaviour & render DestroyImmediate(SteamVR_Behaviour.instance.gameObject); - SteamVR.enabled = false; + SteamVR.enabled = false; // disposes SteamVR // Disable UnityXR XRSettings.LoadDeviceByName(""); XRSettings.enabled = false; - // We don't really need to wait on Stop() + // We don't really need to wait a frame on Stop() } } \ No newline at end of file diff --git a/DesktopVRSwitch/VRModeTrackers/MetaPortTracker.cs b/DesktopVRSwitch/VRModeTrackers/MetaPortTracker.cs index c6a3b73..26dd910 100644 --- a/DesktopVRSwitch/VRModeTrackers/MetaPortTracker.cs +++ b/DesktopVRSwitch/VRModeTrackers/MetaPortTracker.cs @@ -7,8 +7,6 @@ namespace NAK.DesktopVRSwitch.VRModeTrackers; public class MetaPortTracker : VRModeTracker { - private MetaPort _metaPort; - public override void TrackerInit() { VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch; @@ -21,7 +19,7 @@ public class MetaPortTracker : VRModeTracker private void OnPostSwitch(bool intoVR) { - _metaPort = MetaPort.Instance; + MetaPort _metaPort = MetaPort.Instance; if (_metaPort == null) { DesktopVRSwitch.Logger.Error("Error while getting MetaPort!"); @@ -33,11 +31,11 @@ public class MetaPortTracker : VRModeTracker _metaPort.isUsingVr = intoVR; // replace - UpdateRichPresence(); + UpdateRichPresence(_metaPort); ResetSteamVROverrides(intoVR); } - private void UpdateRichPresence() + private void UpdateRichPresence(MetaPort _metaPort) { // Hacky way of updating rich presence if (_metaPort.settings.GetSettingsBool("ImplementationRichPresenceDiscordEnabled", true)) diff --git a/DesktopVRSwitch/VRModeTrackers/MovementSystemTracker.cs b/DesktopVRSwitch/VRModeTrackers/MovementSystemTracker.cs index ac1a90b..534f7a8 100644 --- a/DesktopVRSwitch/VRModeTrackers/MovementSystemTracker.cs +++ b/DesktopVRSwitch/VRModeTrackers/MovementSystemTracker.cs @@ -1,12 +1,11 @@ using ABI_RC.Systems.MovementSystem; - +using System.Collections; using UnityEngine; namespace NAK.DesktopVRSwitch.VRModeTrackers; public class MovementSystemTracker : VRModeTracker { - private MovementSystem _movementSystem; private Vector3 preSwitchWorldPosition; private Quaternion preSwitchWorldRotation; @@ -24,33 +23,68 @@ public class MovementSystemTracker : VRModeTracker VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch; } + private MovementSystem GetMovementSystemInstance() + { + MovementSystem _movementSystem = MovementSystem.Instance; + if (_movementSystem == null) + { + DesktopVRSwitch.Logger.Error("Error while getting MovementSystem!"); + } + return _movementSystem; + } + private void OnPreSwitch(bool intoVR) { - _movementSystem = MovementSystem.Instance; + MovementSystem _movementSystem = GetMovementSystemInstance(); + if (_movementSystem != null) + { + DesktopVRSwitch.Logger.Msg("Storing player world position and rotation."); + preSwitchWorldPosition = _movementSystem.rotationPivot.transform.position; + preSwitchWorldPosition.y = _movementSystem.transform.position.y; + preSwitchWorldRotation = _movementSystem.rotationPivot.transform.rotation; - preSwitchWorldPosition = Utils.GetPlayerRootPosition(); - preSwitchWorldRotation = _movementSystem.rotationPivot.transform.rotation; - - _movementSystem.SetImmobilized(true); - _movementSystem.ChangeCrouch(false); - _movementSystem.ChangeProne(false); + _movementSystem.ChangeCrouch(false); + _movementSystem.ChangeProne(false); + _movementSystem.SetImmobilized(true); + } } private void OnFailedSwitch(bool intoVR) { - _movementSystem.SetImmobilized(false); + MovementSystem _movementSystem = GetMovementSystemInstance(); + if (_movementSystem != null) + { + DesktopVRSwitch.Logger.Msg("Resetting MovementSystem mobility."); + _movementSystem.SetImmobilized(false); + } } private void OnPostSwitch(bool intoVR) { - _movementSystem.rotationPivot = Utils.GetPlayerCameraObject(intoVR).transform; - _movementSystem.TeleportToPosRot(preSwitchWorldPosition, preSwitchWorldRotation, false); + // Lazy + MelonLoader.MelonCoroutines.Start(TeleportFrameAfter(intoVR)); + } - if (!intoVR) - _movementSystem.UpdateColliderCenter(_movementSystem.transform.position); + private IEnumerator TeleportFrameAfter(bool intoVR) + { + yield return null; // need to wait a frame - _movementSystem.SetImmobilized(false); - _movementSystem.ChangeCrouch(false); - _movementSystem.ChangeProne(false); + MovementSystem _movementSystem = GetMovementSystemInstance(); + if (_movementSystem != null) + { + DesktopVRSwitch.Logger.Msg("Resetting MovementSystem mobility and applying stored position and rotation."); + + _movementSystem.rotationPivot = Utils.GetPlayerCameraObject(intoVR).transform; + _movementSystem.TeleportToPosRot(preSwitchWorldPosition, preSwitchWorldRotation, false); + + if (!intoVR) + _movementSystem.UpdateColliderCenter(_movementSystem.transform.position); + + _movementSystem.ChangeCrouch(false); + _movementSystem.ChangeProne(false); + _movementSystem.SetImmobilized(false); + } + + yield break; } } \ No newline at end of file diff --git a/DesktopVRSwitch/VRModeTrackers/PlayerSetupTracker.cs b/DesktopVRSwitch/VRModeTrackers/PlayerSetupTracker.cs index bac1c63..825cd57 100644 --- a/DesktopVRSwitch/VRModeTrackers/PlayerSetupTracker.cs +++ b/DesktopVRSwitch/VRModeTrackers/PlayerSetupTracker.cs @@ -34,7 +34,7 @@ public class PlayerSetupTracker : VRModeTracker CVR_DesktopCameraController._cam = _playerSetup.desktopCamera.GetComponent(); CVR_DesktopCameraController.UpdateFov(); - + // UICamera has a script that copies the FOV from the desktop cam. // Toggling the cameras on/off resets the aspect ratio, // so when rigs switch, that is already handled.