diff --git a/DesktopVRSwitch/DesktopVRSwitch.csproj b/DesktopVRSwitch/DesktopVRSwitch.csproj
index 66a50a8..e94f9dc 100644
--- a/DesktopVRSwitch/DesktopVRSwitch.csproj
+++ b/DesktopVRSwitch/DesktopVRSwitch.csproj
@@ -1,2 +1,2 @@
-
+
diff --git a/DesktopVRSwitch/DesktopVRSwitcher.cs b/DesktopVRSwitch/DesktopVRSwitcher.cs
index 50b565b..1fb5a15 100644
--- a/DesktopVRSwitch/DesktopVRSwitcher.cs
+++ b/DesktopVRSwitch/DesktopVRSwitcher.cs
@@ -1,4 +1,6 @@
-using NAK.DesktopVRSwitch.Patches;
+/**
+
+using NAK.DesktopVRSwitch.Patches;
using System.Collections;
using UnityEngine;
using UnityEngine.XR;
@@ -16,7 +18,7 @@ using ABI_RC.Core;
QualitySettings.vSyncCount = 0;
Time.fixedDeltaTime = Time.timeScale / hmd_DisplayFrequency;
-**/
+**
namespace NAK.DesktopVRSwitch;
@@ -130,35 +132,36 @@ public class DesktopVRSwitcher : MonoBehaviour
public void PostVRModeSwitch(bool enableVR)
{
if (_softVRSwitch) return;
- //close the menus
- TryCatchHell.CloseCohtmlMenus();
- //the base of VR checks
- TryCatchHell.SetCheckVR(enableVR);
- TryCatchHell.SetMetaPort(enableVR);
-
- //game basics for functional gameplay post switch
- TryCatchHell.RepositionCohtmlHud(enableVR);
- TryCatchHell.UpdateHudOperations(enableVR);
- TryCatchHell.DisableMirrorCanvas();
- TryCatchHell.SwitchActiveCameraRigs(enableVR);
- TryCatchHell.ResetCVRInputManager();
- TryCatchHell.UpdateRichPresence();
- TryCatchHell.UpdateGestureReconizerCam();
- TryCatchHell.UpdateMenuCoreData(enableVR);
-
- //let tracked objects know we switched
- VRModeSwitchTracker.PostVRModeSwitch(enableVR);
-
- //reload avatar by default, optional for debugging
- if (_reloadLocalAvatar)
- {
- TryCatchHell.ReloadLocalAvatar();
- }
+ SetupVR(enableVR);
_switchInProgress = false;
}
+ public void SetupVR(bool intoVR)
+ {
+ List actions = new List
+ {
+ TryCatchHell.SetCheckVR,
+ TryCatchHell.SetMetaPort,
+ TryCatchHell.RepositionCohtmlHud,
+ TryCatchHell.UpdateHudOperations,
+ TryCatchHell.DisableMirrorCanvas,
+ TryCatchHell.SwitchActiveCameraRigs,
+ TryCatchHell.ResetCVRInputManager,
+ TryCatchHell.UpdateRichPresence,
+ TryCatchHell.UpdateGestureReconizerCam,
+ TryCatchHell.UpdateMenuCoreData,
+ };
+
+ foreach (var action in actions)
+ {
+ TryCatchHell.TryExecute(action, intoVR);
+ }
+
+ TryCatchHell.TryExecute(VRModeSwitchTracker.PostVRModeSwitch, intoVR);
+ }
+
public void ResetSteamVROverrides()
{
// Reset physics time to Desktop default
@@ -193,3 +196,6 @@ public class DesktopVRSwitcher : MonoBehaviour
}
}
+
+
+**/
\ No newline at end of file
diff --git a/DesktopVRSwitch/HarmonyPatches.cs b/DesktopVRSwitch/HarmonyPatches.cs
index ce8c9b6..6cb7c27 100644
--- a/DesktopVRSwitch/HarmonyPatches.cs
+++ b/DesktopVRSwitch/HarmonyPatches.cs
@@ -1,12 +1,11 @@
using ABI.CCK.Components;
-using ABI_RC.Core.Player;
using ABI_RC.Core.Savior;
using ABI_RC.Core.Util.Object_Behaviour;
using ABI_RC.Systems.IK;
using ABI_RC.Systems.IK.TrackingModules;
-using ABI_RC.Systems.MovementSystem;
using HarmonyLib;
using NAK.DesktopVRSwitch.Patches;
+using NAK.DesktopVRSwitch.VRModeTrackers;
using UnityEngine;
namespace NAK.DesktopVRSwitch.HarmonyPatches;
@@ -15,87 +14,24 @@ class CheckVRPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(CheckVR), nameof(CheckVR.Start))]
- private static void Postfix_CheckVR_Start(ref CheckVR __instance)
+ static void Postfix_CheckVR_Start(ref CheckVR __instance)
{
- __instance.gameObject.AddComponent();
- }
-}
-
-class MovementSystemPatches
-{
- [HarmonyPostfix]
- [HarmonyPatch(typeof(MovementSystem), nameof(MovementSystem.Start))]
- private static void Postfix_MovementSystem_Start(ref MovementSystem __instance)
- {
- __instance.gameObject.AddComponent();
- }
-}
-
-class CVRPickupObjectPatches
-{
- [HarmonyPrefix]
- [HarmonyPatch(typeof(CVRPickupObject), nameof(CVRPickupObject.Start))]
- private static void Prefix_CVRPickupObject_Start(ref CVRPickupObject __instance)
- {
- if (__instance.gripType == CVRPickupObject.GripType.Free) return;
-
- Transform vrOrigin = __instance.gripOrigin;
- Transform desktopOrigin = __instance.gripOrigin.Find("[Desktop]");
- if (vrOrigin != null && desktopOrigin != null)
- {
- var tracker = __instance.gameObject.AddComponent();
- tracker.pickupObject = __instance;
- tracker.storedGripOrigin = (!MetaPort.Instance.isUsingVr ? vrOrigin : desktopOrigin);
- }
- }
-}
-
-class CVRWorldPatches
-{
- [HarmonyPostfix]
- [HarmonyPatch(typeof(CVRWorld), nameof(CVRWorld.SetDefaultCamValues))]
- private static void Postfix_CVRWorld_SetDefaultCamValues()
- {
- ReferenceCameraPatch.OnWorldLoad();
- }
-
- [HarmonyPostfix]
- [HarmonyPatch(typeof(CVRWorld), nameof(CVRWorld.CopyRefCamValues))]
- private static void Postfix_CVRWorld_CopyRefCamValues()
- {
- ReferenceCameraPatch.OnWorldLoad();
- }
-}
-
-class CameraFacingObjectPatches
-{
- [HarmonyPostfix]
- [HarmonyPatch(typeof(CameraFacingObject), nameof(CameraFacingObject.Start))]
- private static void Postfix_CameraFacingObject_Start(ref CameraFacingObject __instance)
- {
- __instance.gameObject.AddComponent();
+ __instance.gameObject.AddComponent();
}
}
class IKSystemPatches
{
- [HarmonyPostfix]
- [HarmonyPatch(typeof(IKSystem), nameof(IKSystem.Start))]
- private static void Postfix_IKSystem_Start(ref IKSystem __instance)
- {
- __instance.gameObject.AddComponent();
- }
-
[HarmonyPostfix] //lazy fix so i dont need to wait few frames
[HarmonyPatch(typeof(TrackingPoint), nameof(TrackingPoint.Initialize))]
- private static void Postfix_TrackingPoint_Initialize(ref TrackingPoint __instance)
+ static void Postfix_TrackingPoint_Initialize(ref TrackingPoint __instance)
{
__instance.referenceTransform.localScale = Vector3.one;
}
[HarmonyPostfix] //lazy fix so device indecies can change properly
[HarmonyPatch(typeof(SteamVRTrackingModule), nameof(SteamVRTrackingModule.ModuleDestroy))]
- private static void Postfix_SteamVRTrackingModule_ModuleDestroy(ref SteamVRTrackingModule __instance)
+ static void Postfix_SteamVRTrackingModule_ModuleDestroy(ref SteamVRTrackingModule __instance)
{
for (int i = 0; i < __instance.TrackingPoints.Count; i++)
{
@@ -105,12 +41,29 @@ class IKSystemPatches
}
}
-class VRTrackerManagerPatches
+class CVRWorldPatches
{
[HarmonyPostfix]
- [HarmonyPatch(typeof(VRTrackerManager), nameof(VRTrackerManager.Start))]
- private static void Postfix_VRTrackerManager_Start(ref VRTrackerManager __instance)
+ [HarmonyPatch(typeof(CVRWorld), nameof(CVRWorld.SetDefaultCamValues))]
+ static void Postfix_CVRWorld_SetDefaultCamValues()
{
- __instance.gameObject.AddComponent();
+ ReferenceCameraPatch.OnWorldLoad();
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(CVRWorld), nameof(CVRWorld.CopyRefCamValues))]
+ static void Postfix_CVRWorld_CopyRefCamValues()
+ {
+ ReferenceCameraPatch.OnWorldLoad();
+ }
+}
+
+class CameraFacingObjectPatches
+{
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(CameraFacingObject), nameof(CameraFacingObject.Start))]
+ static void Postfix_CameraFacingObject_Start(ref CameraFacingObject __instance)
+ {
+ __instance.gameObject.AddComponent();
}
}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Main.cs b/DesktopVRSwitch/Main.cs
index 181ae57..134bc8c 100644
--- a/DesktopVRSwitch/Main.cs
+++ b/DesktopVRSwitch/Main.cs
@@ -1,4 +1,6 @@
using MelonLoader;
+using NAK.DesktopVRSwitch.VRModeTrackers;
+using UnityEngine;
/**
I know the TryCatchHell thing might be a bit exessive, but it is
@@ -18,23 +20,66 @@ namespace NAK.DesktopVRSwitch;
public class DesktopVRSwitch : MelonMod
{
internal static MelonLogger.Instance Logger;
-
+
public static readonly MelonPreferences_Category Category =
MelonPreferences.CreateCategory(nameof(DesktopVRSwitch));
public static readonly MelonPreferences_Entry EntryEnterCalibrationOnSwitch =
Category.CreateEntry("Enter Calibration on Switch", true, description: "Should you automatically be placed into calibration after switch if FBT is available? Overridden by Save Calibration IK setting.");
+ public static readonly MelonPreferences_Entry EntryUseTransitionOnSwitch =
+ Category.CreateEntry("Use Transition on Switch", true, description: "Should the world transition play on VRMode switch?");
+
public override void OnInitializeMelon()
{
Logger = LoggerInstance;
+
+ RegisterVRModeTrackers();
+
+ // main manager
ApplyPatches(typeof(HarmonyPatches.CheckVRPatches));
- ApplyPatches(typeof(HarmonyPatches.CVRPickupObjectPatches));
- ApplyPatches(typeof(HarmonyPatches.CVRWorldPatches));
+ // nameplate fixes
ApplyPatches(typeof(HarmonyPatches.CameraFacingObjectPatches));
+ // lazy fix to reset iksystem
ApplyPatches(typeof(HarmonyPatches.IKSystemPatches));
- ApplyPatches(typeof(HarmonyPatches.MovementSystemPatches));
- ApplyPatches(typeof(HarmonyPatches.VRTrackerManagerPatches));
+ // post processing fixes
+ ApplyPatches(typeof(HarmonyPatches.CVRWorldPatches));
+ }
+
+ public override void OnUpdate()
+ {
+ if (Input.GetKeyDown(KeyCode.F6) && Input.GetKey(KeyCode.LeftControl))
+ {
+ VRModeSwitchManager.Instance?.StartSwitch();
+ }
+ }
+
+ void RegisterVRModeTrackers()
+ {
+ // Core trackers
+ VRModeSwitchManager.RegisterVRModeTracker(new CheckVRTracker());
+ VRModeSwitchManager.RegisterVRModeTracker(new MetaPortTracker());
+
+ // HUD trackers
+ VRModeSwitchManager.RegisterVRModeTracker(new CohtmlHudTracker());
+ VRModeSwitchManager.RegisterVRModeTracker(new HudOperationsTracker());
+
+ // Player trackers
+ VRModeSwitchManager.RegisterVRModeTracker(new PlayerSetupTracker());
+ VRModeSwitchManager.RegisterVRModeTracker(new MovementSystemTracker());
+ VRModeSwitchManager.RegisterVRModeTracker(new IKSystemTracker());
+
+ // Menu trackers
+ VRModeSwitchManager.RegisterVRModeTracker(new CVR_MenuManagerTracker());
+ VRModeSwitchManager.RegisterVRModeTracker(new ViewManagerTracker());
+
+ // Interaction trackers
+ VRModeSwitchManager.RegisterVRModeTracker(new CVRInputManagerTracker());
+ VRModeSwitchManager.RegisterVRModeTracker(new CVR_InteractableManagerTracker());
+ VRModeSwitchManager.RegisterVRModeTracker(new CVRGestureRecognizerTracker());
+
+ // Portable camera tracker
+ VRModeSwitchManager.RegisterVRModeTracker(new PortableCameraTracker());
}
void ApplyPatches(Type type)
diff --git a/DesktopVRSwitch/Patches/CVRPickupObjectTracker.cs b/DesktopVRSwitch/Patches/CVRPickupObjectTracker.cs
deleted file mode 100644
index f37acd1..0000000
--- a/DesktopVRSwitch/Patches/CVRPickupObjectTracker.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using ABI.CCK.Components;
-using UnityEngine;
-
-//Thanks Ben! I was scared of transpiler so I reworked a bit...
-
-namespace NAK.DesktopVRSwitch.Patches;
-
-public class CVRPickupObjectTracker : MonoBehaviour
-{
- public CVRPickupObject pickupObject;
- public Transform storedGripOrigin;
-
- void Start()
- {
- VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
- }
-
- void OnDestroy()
- {
- VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
- }
-
- public void PostVRModeSwitch(bool enableVR, Camera activeCamera)
- {
- if (pickupObject != null)
- {
- if (pickupObject._controllerRay != null) pickupObject._controllerRay.DropObject(true);
- (storedGripOrigin, pickupObject.gripOrigin) = (pickupObject.gripOrigin, storedGripOrigin);
- }
- }
-}
diff --git a/DesktopVRSwitch/Patches/CameraFacingObjectTracker.cs b/DesktopVRSwitch/Patches/CameraFacingObjectTracker.cs
deleted file mode 100644
index 89bb90e..0000000
--- a/DesktopVRSwitch/Patches/CameraFacingObjectTracker.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using ABI_RC.Core.Util.Object_Behaviour;
-using UnityEngine;
-
-namespace NAK.DesktopVRSwitch.Patches;
-
-public class CameraFacingObjectTracker : MonoBehaviour
-{
- public CameraFacingObject cameraFacingObject;
-
- void Start()
- {
- cameraFacingObject = GetComponent();
- VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
- }
-
- void OnDestroy()
- {
- VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
- }
-
- public void PostVRModeSwitch(bool enableVR, Camera activeCamera)
- {
- cameraFacingObject.m_Camera = activeCamera;
- }
-}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Patches/IKSystemTracker.cs b/DesktopVRSwitch/Patches/IKSystemTracker.cs
deleted file mode 100644
index 36d8c0c..0000000
--- a/DesktopVRSwitch/Patches/IKSystemTracker.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-using ABI_RC.Systems.IK;
-using ABI_RC.Systems.IK.SubSystems;
-using ABI_RC.Systems.IK.TrackingModules;
-using UnityEngine;
-
-namespace NAK.DesktopVRSwitch.Patches;
-
-public class IKSystemTracker : MonoBehaviour
-{
- public IKSystem ikSystem;
-
- void Start()
- {
- ikSystem = GetComponent();
- VRModeSwitchTracker.OnPreVRModeSwitch += PreVRModeSwitch;
- VRModeSwitchTracker.OnFailVRModeSwitch += FailedVRModeSwitch;
- VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
- }
- void OnDestroy()
- {
- VRModeSwitchTracker.OnPreVRModeSwitch -= PreVRModeSwitch;
- VRModeSwitchTracker.OnFailVRModeSwitch -= FailedVRModeSwitch;
- VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
- }
-
- public void PreVRModeSwitch(bool enableVR, Camera activeCamera)
- {
- BodySystem.TrackingEnabled = false;
- BodySystem.TrackingPositionWeight = 0f;
- BodySystem.TrackingLocomotionEnabled = false;
- if (IKSystem.vrik != null)
- IKSystem.vrik.enabled = false;
- }
-
- public void FailedVRModeSwitch(bool enableVR, Camera activeCamera)
- {
- BodySystem.TrackingEnabled = true;
- BodySystem.TrackingPositionWeight = 1f;
- BodySystem.TrackingLocomotionEnabled = true;
- if (IKSystem.vrik != null)
- IKSystem.vrik.enabled = true;
- }
-
- public void PostVRModeSwitch(bool enableVR, Camera activeCamera)
- {
- if (IKSystem.vrik != null)
- DestroyImmediate(IKSystem.vrik);
-
- //make sure you are fully tracking
- BodySystem.TrackingEnabled = true;
- BodySystem.TrackingPositionWeight = 1f;
- BodySystem.TrackingLocomotionEnabled = true;
- BodySystem.isCalibratedAsFullBody = false;
- BodySystem.isCalibrating = false;
- BodySystem.isRecalibration = false;
- //make it so you dont instantly end up in FBT from Desktop
- IKSystem.firstAvatarLoaded = DesktopVRSwitch.EntryEnterCalibrationOnSwitch.Value;
- //turn of finger tracking just in case user switched controllers
- ikSystem.FingerSystem.controlActive = false;
-
- //vrik should be deleted by avatar switch
-
- SetupSteamVRTrackingModule(enableVR);
- }
-
- void SetupSteamVRTrackingModule(bool enableVR)
- {
- var openVRModule = ikSystem._trackingModules.OfType().FirstOrDefault();
-
- if (openVRModule != null)
- {
- if (enableVR)
- {
- openVRModule.ModuleStart();
- }
- else
- {
- openVRModule.ModuleDestroy();
- }
- }
- else if (enableVR)
- {
- var newVRModule = new SteamVRTrackingModule();
- ikSystem.AddTrackingModule(newVRModule);
- }
- }
-}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Patches/MovementSystemTracker.cs b/DesktopVRSwitch/Patches/MovementSystemTracker.cs
deleted file mode 100644
index ddfed75..0000000
--- a/DesktopVRSwitch/Patches/MovementSystemTracker.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using ABI_RC.Systems.MovementSystem;
-using UnityEngine;
-
-namespace NAK.DesktopVRSwitch.Patches;
-
-public class MovementSystemTracker : MonoBehaviour
-{
- public MovementSystem movementSystem;
- public Vector3 preSwitchWorldPosition;
- public Quaternion preSwitchWorldRotation;
-
- void Start()
- {
- movementSystem = GetComponent();
- VRModeSwitchTracker.OnPreVRModeSwitch += PreVRModeSwitch;
- VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
- }
-
- void OnDestroy()
- {
- VRModeSwitchTracker.OnPreVRModeSwitch -= PreVRModeSwitch;
- VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
- }
-
- public void PreVRModeSwitch(bool enableVR, Camera activeCamera)
- {
- //correct rotationPivot y position, so we dont teleport up/down
- Vector3 position = movementSystem.rotationPivot.transform.position;
- position.y = movementSystem.transform.position.y;
- preSwitchWorldPosition = position;
- preSwitchWorldRotation = movementSystem.rotationPivot.transform.rotation;
- //ChilloutVR does not use VRIK root right, so avatar root is VR player root.
- //This causes desync between VR and Desktop positions & collision on switch.
-
- //I correct for this in lazy way, but i use rotationPivot instead of avatar root,
- //so the user can still switch even if avatar is null (if it failed to load for example).
-
- movementSystem.ChangeCrouch(false);
- movementSystem.ChangeProne(false);
- }
-
- public void PostVRModeSwitch(bool enableVR, Camera activeCamera)
- {
- //immediatly update camera to new camera transform
- movementSystem.rotationPivot = activeCamera.transform;
- //lazy way of correcting Desktop & VR offset issue (game does the maths)
- movementSystem.TeleportToPosRot(preSwitchWorldPosition, preSwitchWorldRotation, false);
- //recenter desktop collision to player object
- if (!enableVR) movementSystem.UpdateColliderCenter(movementSystem.transform.position);
-
- movementSystem.ChangeCrouch(false);
- movementSystem.ChangeProne(false);
- }
-}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Patches/VRModeSwitchTracker.cs b/DesktopVRSwitch/Patches/VRModeSwitchTracker.cs
deleted file mode 100644
index 74822a0..0000000
--- a/DesktopVRSwitch/Patches/VRModeSwitchTracker.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using ABI_RC.Core.Player;
-using UnityEngine;
-using UnityEngine.Events;
-
-namespace NAK.DesktopVRSwitch.Patches;
-
-public class VRModeSwitchTracker
-{
- public static event UnityAction OnPreVRModeSwitch;
- public static event UnityAction OnPostVRModeSwitch;
- public static event UnityAction OnFailVRModeSwitch;
-
- public static void PreVRModeSwitch(bool enableVR)
- {
- TryCatchHell.TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Invoking VRModeSwitchTracker.OnPreVRModeSwitch.");
- Camera activeCamera = PlayerSetup.Instance.GetActiveCamera().GetComponent();
- VRModeSwitchTracker.OnPreVRModeSwitch?.Invoke(enableVR, activeCamera);
- },
- "Error while invoking VRModeSwitchTracker.OnPreVRModeSwitch. Did someone do a fucky?");
- }
-
- public static void PostVRModeSwitch(bool enableVR)
- {
- TryCatchHell.TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Invoking VRModeSwitchTracker.OnPostVRModeSwitch.");
- Camera activeCamera = PlayerSetup.Instance.GetActiveCamera().GetComponent();
- VRModeSwitchTracker.OnPostVRModeSwitch?.Invoke(enableVR, activeCamera);
- },
- "Error while invoking VRModeSwitchTracker.OnPostVRModeSwitch. Did someone do a fucky?");
- }
-
- public static void FailVRModeSwitch(bool enableVR)
- {
- TryCatchHell.TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Invoking VRModeSwitchTracker.OnFailVRModeSwitch.");
- Camera activeCamera = PlayerSetup.Instance.GetActiveCamera().GetComponent();
- VRModeSwitchTracker.OnFailVRModeSwitch?.Invoke(enableVR, activeCamera);
- },
- "Error while invoking OnFailVRModeSwitch.OnPreVRModeSwitch. Did someone do a fucky?");
- }
-}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Patches/VRTrackerManagerTracker.cs b/DesktopVRSwitch/Patches/VRTrackerManagerTracker.cs
deleted file mode 100644
index 3cbaa46..0000000
--- a/DesktopVRSwitch/Patches/VRTrackerManagerTracker.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using ABI_RC.Core.Player;
-using HarmonyLib;
-using UnityEngine;
-
-namespace NAK.DesktopVRSwitch.Patches;
-
-public class VRTrackerManagerTracker : MonoBehaviour
-{
- public VRTrackerManager vrTrackerManager;
-
- void Start()
- {
- vrTrackerManager = GetComponent();
- VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
- }
- void OnDestroy()
- {
- VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
- }
-
- public void PostVRModeSwitch(bool enableVR, Camera activeCamera)
- {
- //force the VRTrackerManager to reset anything its stored
- //this makes it get correct Left/Right hand if entering VR with different controllers
- //or if you restarted SteamVR and controllers are now in swapped index
- vrTrackerManager.poses = null;
- vrTrackerManager.leftHand = null;
- vrTrackerManager.rightHand = null;
- vrTrackerManager.hasCheckedForKnuckles = false;
- }
-}
\ No newline at end of file
diff --git a/DesktopVRSwitch/TryCatchHell.cs b/DesktopVRSwitch/TryCatchHell.cs
index 92ff333..51f258b 100644
--- a/DesktopVRSwitch/TryCatchHell.cs
+++ b/DesktopVRSwitch/TryCatchHell.cs
@@ -1,188 +1,67 @@
-using ABI_RC.Core;
-using ABI_RC.Core.EventSystem;
-using ABI_RC.Core.InteractionSystem;
-using ABI_RC.Core.Player;
-using ABI_RC.Core.Savior;
-using ABI_RC.Core.UI;
-using ABI_RC.Systems.Camera;
-using UnityEngine;
+using UnityEngine;
namespace NAK.DesktopVRSwitch;
internal class TryCatchHell
{
- internal static void TryCatchWrapper(Action action, string errorMsg, params object[] msgArgs)
+ public delegate void TryAction(bool intoVR);
+
+ public static void TryExecute(TryAction action, bool intoVR)
{
try
{
- action();
+ action(intoVR);
}
catch (Exception ex)
{
- DesktopVRSwitch.Logger.Error(string.Format(errorMsg, msgArgs));
- DesktopVRSwitch.Logger.Msg(ex.Message);
+ Debug.LogError($"Error executing action: {ex.Message}");
}
}
- internal static void CloseCohtmlMenus()
+ internal static void CloseCohtmlMenus(bool intoVR)
{
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Closing ViewManager & CVR_MenuManager menus.");
- ViewManager.Instance.UiStateToggle(false);
- CVR_MenuManager.Instance.ToggleQuickMenu(false);
- },
- "Setting CheckVR hasVrDeviceLoaded failed.");
+
+
}
- internal static void SetCheckVR(bool enableVR)
+ internal static void RepositionCohtmlHud(bool intoVR)
{
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg($"Setting CheckVR hasVrDeviceLoaded to {enableVR}.");
- CheckVR.Instance.hasVrDeviceLoaded = enableVR;
- },
- "Setting CheckVR hasVrDeviceLoaded failed.");
+
}
- internal static void SetMetaPort(bool enableVR)
+ internal static void UpdateHudOperations(bool intoVR)
{
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg($"Setting MetaPort isUsingVr to {enableVR}.");
- MetaPort.Instance.isUsingVr = enableVR;
- },
- "Setting MetaPort isUsingVr failed.");
+
}
- internal static void RepositionCohtmlHud(bool enableVR)
+ internal static void DisableMirrorCanvas(bool intoVR)
{
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Configuring new hud affinity for CohtmlHud.");
- CohtmlHud.Instance.gameObject.transform.parent = enableVR ? PlayerSetup.Instance.vrCamera.transform : PlayerSetup.Instance.desktopCamera.transform;
- CVRTools.ConfigureHudAffinity();
- CohtmlHud.Instance.gameObject.transform.localScale = new Vector3(1.2f, 1f, 1.2f);
- },
- "Error parenting CohtmlHud to active camera.");
+
}
- internal static void UpdateHudOperations(bool enableVR)
+ internal static void SwitchActiveCameraRigs(bool intoVR)
{
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Switching HudOperations worldLoadingItem & worldLoadStatus.");
- HudOperations.Instance.worldLoadingItem = enableVR ? HudOperations.Instance.worldLoadingItemVr : HudOperations.Instance.worldLoadingItemDesktop;
- HudOperations.Instance.worldLoadStatus = enableVR ? HudOperations.Instance.worldLoadStatusVr : HudOperations.Instance.worldLoadStatusDesktop;
- },
- "Failed switching HudOperations objects.");
+
+
}
- internal static void DisableMirrorCanvas()
+ internal static void PauseInputInteractions(bool intoVR)
{
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Forcing PortableCamera canvas mirroring off.");
- //tell the game we are in mirror mode so itll disable it (if enabled)
- PortableCamera.Instance.mode = MirroringMode.Mirror;
- PortableCamera.Instance.ChangeMirroring();
- },
- "Failed to disable PortableCamera canvas mirroring.");
+
}
- internal static void SwitchActiveCameraRigs(bool enableVR)
+ internal static void ReloadLocalAvatar(bool intoVR)
{
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Switching active PlayerSetup camera rigs. Updating Desktop camera FOV.");
- PlayerSetup.Instance.desktopCameraRig.SetActive(!enableVR);
- PlayerSetup.Instance.vrCameraRig.SetActive(enableVR);
- CVR_DesktopCameraController.UpdateFov();
- //uicamera has script that copies fov from desktop cam
- //toggling the cameras on/off resets aspect ratio
- //so when rigs switch, that is already handled
- },
- "Failed to switch active camera rigs or update Desktop camera FOV.");
+
}
- internal static void PauseInputInteractions(bool toggle)
+ internal static void UpdateGestureReconizerCam(bool intoVR)
{
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg($"Setting CVRInputManager inputEnabled & CVR_InteractableManager enableInteractions to {!toggle}");
- CVRInputManager.Instance.inputEnabled = !toggle;
- CVR_InteractableManager.enableInteractions = !toggle;
- },
- "Failed to toggle CVRInputManager inputEnabled & CVR_InteractableManager enableInteractions.");
+
}
- internal static void ResetCVRInputManager()
+ internal static void UpdateMenuCoreData(bool intoVR)
{
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Resetting CVRInputManager inputs.");
- //just in case
- CVRInputManager.Instance.blockedByUi = false;
- //sometimes head can get stuck, so just in case
- CVRInputManager.Instance.independentHeadToggle = false;
- //just nice to load into desktop with idle gesture
- CVRInputManager.Instance.gestureLeft = 0f;
- CVRInputManager.Instance.gestureLeftRaw = 0f;
- CVRInputManager.Instance.gestureRight = 0f;
- CVRInputManager.Instance.gestureRightRaw = 0f;
- //turn off finger tracking input
- CVRInputManager.Instance.individualFingerTracking = false;
- },
- "Failed to reset CVRInputManager inputs.");
- }
- internal static void ReloadLocalAvatar()
- {
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Attempting to reload current local avatar from GUID.");
- AssetManagement.Instance.LoadLocalAvatar(MetaPort.Instance.currentAvatarGuid);
- },
- "Failed to reload local avatar.");
- }
-
- internal static void UpdateRichPresence()
- {
- TryCatchWrapper(() =>
- {
- if (MetaPort.Instance.settings.GetSettingsBool("ImplementationRichPresenceDiscordEnabled", true))
- {
- DesktopVRSwitch.Logger.Msg("Forcing Discord Rich Presence update.");
- MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceDiscordEnabled", false);
- MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceDiscordEnabled", true);
- }
- if (MetaPort.Instance.settings.GetSettingsBool("ImplementationRichPresenceSteamEnabled", true))
- {
- DesktopVRSwitch.Logger.Msg("Forcing Steam Rich Presence update.");
- MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceSteamEnabled", false);
- MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceSteamEnabled", true);
- }
- },
- "Failed to update Discord & Steam Rich Presence.");
- }
-
- internal static void UpdateGestureReconizerCam()
- {
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Updating CVRGestureRecognizer _camera to active camera.");
- CVRGestureRecognizer.Instance._camera = PlayerSetup.Instance.GetActiveCamera().GetComponent();
- },
- "Failed to update CVRGestureRecognizer camera.");
- }
-
- internal static void UpdateMenuCoreData(bool enableVR)
- {
- TryCatchWrapper(() =>
- {
- DesktopVRSwitch.Logger.Msg("Updating CVR_Menu_Data core data.");
- CVR_MenuManager.Instance.coreData.core.inVr = enableVR;
- },
- "Failed to update CVR_Menu_Data core data.");
}
}
diff --git a/DesktopVRSwitch/Utils.cs b/DesktopVRSwitch/Utils.cs
new file mode 100644
index 0000000..626e2af
--- /dev/null
+++ b/DesktopVRSwitch/Utils.cs
@@ -0,0 +1,24 @@
+using ABI_RC.Core.EventSystem;
+using ABI_RC.Core.Player;
+using ABI_RC.Core.Savior;
+using UnityEngine;
+
+namespace NAK.DesktopVRSwitch;
+
+internal static class Utils
+{
+ internal static GameObject GetPlayerCameraObject(bool intoVR)
+ {
+ if (intoVR)
+ {
+ return PlayerSetup.Instance.vrCamera;
+ }
+ return PlayerSetup.Instance.desktopCamera;
+ }
+
+ internal static void ReloadLocalAvatar()
+ {
+ DesktopVRSwitch.Logger.Msg("Attempting to reload current local avatar from GUID.");
+ AssetManagement.Instance.LoadLocalAvatar(MetaPort.Instance.currentAvatarGuid);
+ }
+}
diff --git a/DesktopVRSwitch/VRModeTrackers/CVRGestureRecognizerTracker.cs b/DesktopVRSwitch/VRModeTrackers/CVRGestureRecognizerTracker.cs
new file mode 100644
index 0000000..b87a7d7
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/CVRGestureRecognizerTracker.cs
@@ -0,0 +1,30 @@
+using ABI_RC.Core.Savior;
+using UnityEngine;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class CVRGestureRecognizerTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ CVRGestureRecognizer _cvrGestureRecognizer = CVRGestureRecognizer.Instance;
+ if (_cvrGestureRecognizer == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting CVRGestureRecognizer!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg("Updating CVRGestureRecognizer _camera to active camera.");
+
+ _cvrGestureRecognizer._camera = Utils.GetPlayerCameraObject(intoVR).GetComponent();
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/CVRInputManagerTracker.cs b/DesktopVRSwitch/VRModeTrackers/CVRInputManagerTracker.cs
new file mode 100644
index 0000000..7ff3ddc
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/CVRInputManagerTracker.cs
@@ -0,0 +1,41 @@
+using ABI_RC.Core.Savior;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class CVRInputManagerTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ void OnPostSwitch(bool intoVR)
+ {
+ CVRInputManager _cvrInputManager = CVRInputManager.Instance;
+ if (_cvrInputManager == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting CVRInputManager!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg("Resetting CVRInputManager inputs.");
+
+ _cvrInputManager.inputEnabled = true;
+
+ //just in case
+ _cvrInputManager.blockedByUi = false;
+ //sometimes head can get stuck, so just in case
+ _cvrInputManager.independentHeadToggle = false;
+ //just nice to load into desktop with idle gesture
+ _cvrInputManager.gestureLeft = 0f;
+ _cvrInputManager.gestureLeftRaw = 0f;
+ _cvrInputManager.gestureRight = 0f;
+ _cvrInputManager.gestureRightRaw = 0f;
+ //turn off finger tracking input
+ _cvrInputManager.individualFingerTracking = false;
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/CVRPickupObjectTracker.cs b/DesktopVRSwitch/VRModeTrackers/CVRPickupObjectTracker.cs
new file mode 100644
index 0000000..42f9fe4
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/CVRPickupObjectTracker.cs
@@ -0,0 +1,34 @@
+using ABI.CCK.Components;
+using UnityEngine;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class CVRPickupObjectTracker : MonoBehaviour
+{
+ private CVRPickupObject _pickupObject;
+ private Transform _storedGripOrigin;
+
+ public CVRPickupObjectTracker(CVRPickupObject pickupObject, Transform storedGripOrigin)
+ {
+ this._pickupObject = pickupObject;
+ this._storedGripOrigin = storedGripOrigin;
+ }
+
+ private void OnDestroy()
+ {
+
+ }
+
+ public void OnPostSwitch(bool intoVR)
+ {
+ if (_pickupObject != null)
+ {
+ // Drop the object if it is being held locally
+ if (_pickupObject._controllerRay != null)
+ _pickupObject._controllerRay.DropObject(true);
+
+ // Swap the grip origins
+ (_storedGripOrigin, _pickupObject.gripOrigin) = (_pickupObject.gripOrigin, _storedGripOrigin);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/CVR_InteractableManagerTracker.cs b/DesktopVRSwitch/VRModeTrackers/CVR_InteractableManagerTracker.cs
new file mode 100644
index 0000000..824d72a
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/CVR_InteractableManagerTracker.cs
@@ -0,0 +1,29 @@
+using ABI_RC.Core.InteractionSystem;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class CVR_InteractableManagerTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ CVR_InteractableManager _cvrInteractableManager = CVR_InteractableManager.Instance;
+ if (_cvrInteractableManager == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting CVR_InteractableManager!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg($"Setting CVRInputManager inputEnabled & CVR_InteractableManager enableInteractions to {!intoVR}");
+
+ CVR_InteractableManager.enableInteractions = !intoVR;
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/CVR_MenuManagerTracker.cs b/DesktopVRSwitch/VRModeTrackers/CVR_MenuManagerTracker.cs
new file mode 100644
index 0000000..dcf18c6
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/CVR_MenuManagerTracker.cs
@@ -0,0 +1,44 @@
+using ABI_RC.Core.InteractionSystem;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class CVR_MenuManagerTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPreVRModeSwitch += OnPreSwitch;
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPreVRModeSwitch -= OnPreSwitch;
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPreSwitch(bool intoVR)
+ {
+ CVR_MenuManager _cvrMenuManager = CVR_MenuManager.Instance;
+ if (_cvrMenuManager == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting CVR_MenuManager!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg("Closing CVR_MenuManager - Quick Menu.");
+
+ _cvrMenuManager.ToggleQuickMenu(false);
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ CVR_MenuManager _cvrMenuManager = CVR_MenuManager.Instance;
+ if (_cvrMenuManager == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting CVR_MenuManager!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg("Updating CVR_Menu_Data core data.");
+
+ _cvrMenuManager.coreData.core.inVr = intoVR;
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/CameraFacingObjectTracker.cs b/DesktopVRSwitch/VRModeTrackers/CameraFacingObjectTracker.cs
new file mode 100644
index 0000000..504b76a
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/CameraFacingObjectTracker.cs
@@ -0,0 +1,27 @@
+using ABI_RC.Core.Util.Object_Behaviour;
+using UnityEngine;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class CameraFacingObjectTracker : MonoBehaviour
+{
+ private CameraFacingObject _cameraFacingObject;
+
+ public CameraFacingObjectTracker(CameraFacingObject cameraFacingObject)
+ {
+ this._cameraFacingObject = cameraFacingObject;
+ }
+
+ private void OnDestroy()
+ {
+ }
+
+ public void OnPreSwitch(bool intoVR) { }
+
+ public void OnFailedSwitch(bool intoVR) { }
+
+ public void OnPostSwitch(bool intoVR)
+ {
+ _cameraFacingObject.m_Camera = Utils.GetPlayerCameraObject(intoVR).GetComponent();
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/CheckVRTracker.cs b/DesktopVRSwitch/VRModeTrackers/CheckVRTracker.cs
new file mode 100644
index 0000000..7dfa7e4
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/CheckVRTracker.cs
@@ -0,0 +1,29 @@
+using ABI_RC.Core.Savior;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class CheckVRTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ CheckVR _checkVR = CheckVR.Instance;
+ if (_checkVR == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting CheckVR!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg($"Setting CheckVR hasVrDeviceLoaded to {intoVR}.");
+
+ _checkVR.hasVrDeviceLoaded = intoVR;
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/CohtmlHudTracker.cs b/DesktopVRSwitch/VRModeTrackers/CohtmlHudTracker.cs
new file mode 100644
index 0000000..e58baef
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/CohtmlHudTracker.cs
@@ -0,0 +1,34 @@
+using ABI_RC.Core.Player;
+using ABI_RC.Core.UI;
+using UnityEngine;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class CohtmlHudTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ CohtmlHud _cohtmlHud = CohtmlHud.Instance;
+ if (_cohtmlHud == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting CohtmlHud!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg("Configuring new hud affinity for CohtmlHud.");
+
+ _cohtmlHud.gameObject.transform.parent = intoVR ? PlayerSetup.Instance.vrCamera.transform : PlayerSetup.Instance.desktopCamera.transform;
+ // This handles rotation and position
+ ABI_RC.Core.CVRTools.ConfigureHudAffinity();
+ _cohtmlHud.gameObject.transform.localScale = new Vector3(1.2f, 1f, 1.2f);
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/HudOperationsTracker.cs b/DesktopVRSwitch/VRModeTrackers/HudOperationsTracker.cs
new file mode 100644
index 0000000..f25a03a
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/HudOperationsTracker.cs
@@ -0,0 +1,30 @@
+using ABI_RC.Core.Player;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class HudOperationsTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ HudOperations _hudOperations = HudOperations.Instance;
+ if (_hudOperations == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting HudOperations!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg("Switching HudOperations worldLoadingItem & worldLoadStatus.");
+
+ _hudOperations.worldLoadingItem = intoVR ? _hudOperations.worldLoadingItemVr : _hudOperations.worldLoadingItemDesktop;
+ _hudOperations.worldLoadStatus = intoVR ? _hudOperations.worldLoadStatusVr : _hudOperations.worldLoadStatusDesktop;
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/IKSystemTracker.cs b/DesktopVRSwitch/VRModeTrackers/IKSystemTracker.cs
new file mode 100644
index 0000000..9e3a300
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/IKSystemTracker.cs
@@ -0,0 +1,87 @@
+using ABI_RC.Systems.IK;
+using ABI_RC.Systems.IK.SubSystems;
+using ABI_RC.Systems.IK.TrackingModules;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class IKSystemTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPreVRModeSwitch += OnPreSwitch;
+ VRModeSwitchManager.OnFailVRModeSwitch += OnFailedSwitch;
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPreVRModeSwitch -= OnPreSwitch;
+ VRModeSwitchManager.OnFailVRModeSwitch -= OnFailedSwitch;
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPreSwitch(bool intoVR)
+ {
+ BodySystem.TrackingEnabled = false;
+ BodySystem.TrackingPositionWeight = 0f;
+ BodySystem.TrackingLocomotionEnabled = false;
+
+ if (IKSystem.vrik != null)
+ IKSystem.vrik.enabled = false;
+ }
+
+ private void OnFailedSwitch(bool intoVR)
+ {
+ BodySystem.TrackingEnabled = true;
+ BodySystem.TrackingPositionWeight = 1f;
+ BodySystem.TrackingLocomotionEnabled = true;
+
+ if (IKSystem.vrik != null)
+ IKSystem.vrik.enabled = true;
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ if (IKSystem.vrik != null)
+ UnityEngine.Object.DestroyImmediate(IKSystem.vrik);
+
+ // Make sure you are fully tracking
+ BodySystem.TrackingEnabled = true;
+ BodySystem.TrackingPositionWeight = 1f;
+ BodySystem.TrackingLocomotionEnabled = true;
+ BodySystem.isCalibratedAsFullBody = false;
+ BodySystem.isCalibrating = false;
+ BodySystem.isRecalibration = false;
+
+ // Make it so you don't instantly end up in FBT from Desktop
+ IKSystem.firstAvatarLoaded = DesktopVRSwitch.EntryEnterCalibrationOnSwitch.Value;
+
+ // Turn off finger tracking just in case the user switched controllers
+ if (IKSystem.Instance != null)
+ IKSystem.Instance.FingerSystem.controlActive = false;
+
+ SetupSteamVRTrackingModule(intoVR);
+ }
+
+ private void SetupSteamVRTrackingModule(bool enableVR)
+ {
+ var openVRModule = IKSystem.Instance._trackingModules.OfType().FirstOrDefault();
+
+ if (openVRModule != null)
+ {
+ if (enableVR)
+ {
+ openVRModule.ModuleStart();
+ }
+ else
+ {
+ openVRModule.ModuleDestroy();
+ }
+ }
+ else if (enableVR)
+ {
+ var newVRModule = new SteamVRTrackingModule();
+ IKSystem.Instance.AddTrackingModule(newVRModule);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/MetaPortTracker.cs b/DesktopVRSwitch/VRModeTrackers/MetaPortTracker.cs
new file mode 100644
index 0000000..d767221
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/MetaPortTracker.cs
@@ -0,0 +1,44 @@
+using ABI_RC.Core.Savior;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class MetaPortTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ MetaPort _metaPort = MetaPort.Instance;
+ if (_metaPort == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting MetaPort!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg($"Setting MetaPort isUsingVr to {intoVR}.");
+
+ // Main thing most of the game checks for if using VR
+ _metaPort.isUsingVr = intoVR;
+
+ // Hacky way of updating rich presence
+ if (_metaPort.settings.GetSettingsBool("ImplementationRichPresenceDiscordEnabled", true))
+ {
+ DesktopVRSwitch.Logger.Msg("Forcing Discord Rich Presence update.");
+ _metaPort.settings.SetSettingsBool("ImplementationRichPresenceDiscordEnabled", false);
+ _metaPort.settings.SetSettingsBool("ImplementationRichPresenceDiscordEnabled", true);
+ }
+ if (_metaPort.settings.GetSettingsBool("ImplementationRichPresenceSteamEnabled", true))
+ {
+ DesktopVRSwitch.Logger.Msg("Forcing Steam Rich Presence update.");
+ _metaPort.settings.SetSettingsBool("ImplementationRichPresenceSteamEnabled", false);
+ _metaPort.settings.SetSettingsBool("ImplementationRichPresenceSteamEnabled", true);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/MovementSystemTracker.cs b/DesktopVRSwitch/VRModeTrackers/MovementSystemTracker.cs
new file mode 100644
index 0000000..a704162
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/MovementSystemTracker.cs
@@ -0,0 +1,48 @@
+using ABI_RC.Systems.MovementSystem;
+using UnityEngine;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class MovementSystemTracker : VRModeTracker
+{
+ private MovementSystem _movementSystem;
+ private Vector3 preSwitchWorldPosition;
+ private Quaternion preSwitchWorldRotation;
+
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPreVRModeSwitch += OnPreSwitch;
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPreVRModeSwitch -= OnPreSwitch;
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPreSwitch(bool intoVR)
+ {
+ _movementSystem = MovementSystem.Instance;
+
+ Vector3 position = _movementSystem.rotationPivot.transform.position;
+ position.y = _movementSystem.transform.position.y;
+ preSwitchWorldPosition = position;
+ preSwitchWorldRotation = _movementSystem.rotationPivot.transform.rotation;
+
+ _movementSystem.ChangeCrouch(false);
+ _movementSystem.ChangeProne(false);
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ _movementSystem.rotationPivot = Utils.GetPlayerCameraObject(intoVR).transform;
+ _movementSystem.TeleportToPosRot(preSwitchWorldPosition, preSwitchWorldRotation, false);
+
+ if (!intoVR)
+ _movementSystem.UpdateColliderCenter(_movementSystem.transform.position);
+
+ _movementSystem.ChangeCrouch(false);
+ _movementSystem.ChangeProne(false);
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/PlayerSetupTracker.cs b/DesktopVRSwitch/VRModeTrackers/PlayerSetupTracker.cs
new file mode 100644
index 0000000..675a41d
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/PlayerSetupTracker.cs
@@ -0,0 +1,38 @@
+using ABI_RC.Core.Player;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class PlayerSetupTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ PlayerSetup _playerSetup = PlayerSetup.Instance;
+ if (_playerSetup == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting PlayerSetup!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg("Switching active PlayerSetup camera rigs. Updating Desktop camera FOV.");
+
+ _playerSetup.desktopCameraRig.SetActive(!intoVR);
+ _playerSetup.vrCameraRig.SetActive(intoVR);
+
+ // This might error if we started in VR.
+ // '_cam' is not set until Start().
+ 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.
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/PortableCameraTracker.cs b/DesktopVRSwitch/VRModeTrackers/PortableCameraTracker.cs
new file mode 100644
index 0000000..f2a616e
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/PortableCameraTracker.cs
@@ -0,0 +1,31 @@
+using ABI_RC.Systems.Camera;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class PortableCameraTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ PortableCamera _portableCamera = PortableCamera.Instance;
+ if (_portableCamera == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting PortableCamera!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg("Forcing PortableCamera canvas mirroring off.");
+
+ // Tell the game we are in mirror mode so it'll disable it (if enabled)
+ _portableCamera.mode = MirroringMode.Mirror;
+ _portableCamera.ChangeMirroring();
+ }
+}
diff --git a/DesktopVRSwitch/VRModeTrackers/VRModeSwitchManager.cs b/DesktopVRSwitch/VRModeTrackers/VRModeSwitchManager.cs
new file mode 100644
index 0000000..d5864de
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/VRModeSwitchManager.cs
@@ -0,0 +1,185 @@
+using ABI_RC.Systems.UI;
+using System.Collections;
+using UnityEngine;
+using UnityEngine.Events;
+using UnityEngine.XR;
+using Valve.VR;
+
+/**
+
+ I am unsure about this observer approach as only a few things need OnPre and OnFailed switch.
+ Those wouldn't be needed if I can start OpenVR before all that anyways.
+
+ Or... I just start OpenVR and see if it worked. OnPreSwitch would only be needed by menus & transition.
+
+ I think I should just use Unity Events as they would allow easier mod support. Subscribe to what you need.
+
+**/
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class VRModeSwitchManager : MonoBehaviour
+{
+ public static VRModeSwitchManager Instance { get; private set; }
+
+ // I don't think I *need* this. Only using cause I don't want stuff just floating off.
+ private static readonly List _vrModeTrackers = new List();
+
+ public static event UnityAction OnPreVRModeSwitch;
+ public static event UnityAction OnPostVRModeSwitch;
+ public static event UnityAction OnFailVRModeSwitch;
+
+ public static void RegisterVRModeTracker(VRModeTracker observer)
+ {
+ _vrModeTrackers.Add(observer);
+ observer.TrackerInit();
+ }
+
+ public static void UnregisterVRModeTracker(VRModeTracker observer)
+ {
+ _vrModeTrackers.Remove(observer);
+ observer.TrackerDestroy();
+ }
+
+ // Settings
+ private bool _useWorldTransition = true;
+ private bool _reloadLocalAvatar = true;
+
+ // Internal
+ private bool _switchInProgress = false;
+
+ void Awake()
+ {
+ if (Instance != null)
+ {
+ DestroyImmediate(this);
+ return;
+ }
+
+ Instance = this;
+ }
+
+ public void StartSwitch()
+ {
+ StartCoroutine(StartSwitchCoroutine());
+ }
+
+ private IEnumerator StartSwitchCoroutine()
+ {
+ if (_switchInProgress)
+ {
+ yield break;
+ }
+ _switchInProgress = true;
+ yield return null;
+
+
+ if (_useWorldTransition) // start visual transition and wait for it to complete
+ yield return WorldTransitionSystem.Instance.StartTransitionCoroutine();
+
+ // Check if OpenVR is running
+ bool isUsingVr = IsInVR();
+
+ InvokeOnPreSwitch(isUsingVr);
+
+ // Start switch
+ if (!isUsingVr)
+ {
+ yield return StartCoroutine(StartOpenVR());
+ }
+ else
+ {
+ yield return StartCoroutine(StopOpenVR());
+ }
+
+ // Check for updated VR mode
+ if (isUsingVr != IsInVR())
+ {
+ InvokeOnPostSwitch(!isUsingVr);
+
+ // reload the local avatar
+ // only reload on success
+ if (_reloadLocalAvatar)
+ Utils.ReloadLocalAvatar();
+ }
+ else
+ {
+ InvokeOnFailedSwitch(!isUsingVr);
+ }
+
+ if (_useWorldTransition) // finish the visual transition and wait
+ yield return WorldTransitionSystem.Instance.ContinueTransitionCoroutine();
+
+ _switchInProgress = false;
+ yield break;
+ }
+
+ private void SafeInvokeUnityEvent(UnityAction switchEvent, bool isUsingVr)
+ {
+ try
+ {
+ switchEvent.Invoke(isUsingVr);
+ }
+ catch (Exception e)
+ {
+ Debug.Log($"Error in event handler: {e}");
+ }
+ }
+
+ private void InvokeOnPreSwitch(bool isUsingVr)
+ {
+ SafeInvokeUnityEvent(OnPreVRModeSwitch, isUsingVr);
+ }
+
+ private void InvokeOnPostSwitch(bool isUsingVr)
+ {
+ SafeInvokeUnityEvent(OnPostVRModeSwitch, isUsingVr);
+ }
+
+ private void InvokeOnFailedSwitch(bool isUsingVr)
+ {
+ SafeInvokeUnityEvent(OnFailVRModeSwitch, isUsingVr);
+ }
+
+ public bool IsInVR() => XRSettings.enabled;
+
+ private IEnumerator StartOpenVR()
+ {
+ XRSettings.LoadDeviceByName("OpenVR");
+ yield return null; //wait a frame before checking
+
+ if (!string.IsNullOrEmpty(XRSettings.loadedDeviceName))
+ {
+ DesktopVRSwitch.Logger.Msg("Starting SteamVR...");
+ XRSettings.enabled = true;
+ SteamVR_Input.Initialize(true);
+ yield return null;
+ yield break;
+ }
+
+ DesktopVRSwitch.Logger.Error("Initializing VR Failed. Is there no VR device connected?");
+ yield return null;
+ yield break;
+ }
+
+ private IEnumerator StopOpenVR()
+ {
+ SteamVR_Behaviour.instance.enabled = false;
+
+ yield return null;
+
+ if (!string.IsNullOrEmpty(XRSettings.loadedDeviceName))
+ {
+ SteamVR_Input.actionSets[0].Deactivate(SteamVR_Input_Sources.Any);
+ XRSettings.LoadDeviceByName("");
+ XRSettings.enabled = false;
+
+ yield return null;
+ yield break;
+ }
+
+ DesktopVRSwitch.Logger.Error("Attempted to exit VR without a VR device loaded.");
+ yield return null;
+ yield break;
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/VRModeTracker.cs b/DesktopVRSwitch/VRModeTrackers/VRModeTracker.cs
new file mode 100644
index 0000000..3b8ede8
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/VRModeTracker.cs
@@ -0,0 +1,7 @@
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class VRModeTracker
+{
+ public virtual void TrackerInit() { }
+ public virtual void TrackerDestroy() { }
+}
diff --git a/DesktopVRSwitch/VRModeTrackers/VRTrackerManagerTracker.cs b/DesktopVRSwitch/VRModeTrackers/VRTrackerManagerTracker.cs
new file mode 100644
index 0000000..cbe079c
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/VRTrackerManagerTracker.cs
@@ -0,0 +1,32 @@
+using ABI_RC.Core.Player;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class VRTrackerManagerTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch += OnPostSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
+ }
+
+ private void OnPostSwitch(bool intoVR)
+ {
+ VRTrackerManager _vrTrackerManager = VRTrackerManager.Instance;
+ if (_vrTrackerManager == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting VRTrackerManager!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg($"Resetting VRTrackerManager.");
+
+ _vrTrackerManager.poses = null;
+ _vrTrackerManager.leftHand = null;
+ _vrTrackerManager.rightHand = null;
+ _vrTrackerManager.hasCheckedForKnuckles = false;
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/VRModeTrackers/ViewManagerTracker.cs b/DesktopVRSwitch/VRModeTrackers/ViewManagerTracker.cs
new file mode 100644
index 0000000..1014b4d
--- /dev/null
+++ b/DesktopVRSwitch/VRModeTrackers/ViewManagerTracker.cs
@@ -0,0 +1,29 @@
+using ABI_RC.Core.InteractionSystem;
+
+namespace NAK.DesktopVRSwitch.VRModeTrackers;
+
+public class ViewManagerTracker : VRModeTracker
+{
+ public override void TrackerInit()
+ {
+ VRModeSwitchManager.OnPreVRModeSwitch += OnPreSwitch;
+ }
+
+ public override void TrackerDestroy()
+ {
+ VRModeSwitchManager.OnPreVRModeSwitch -= OnPreSwitch;
+ }
+
+ public void OnPreSwitch(bool intoVR)
+ {
+ ViewManager _viewManager = ViewManager.Instance;
+ if (_viewManager == null)
+ {
+ DesktopVRSwitch.Logger.Error("Error while getting ViewManager!");
+ return;
+ }
+ DesktopVRSwitch.Logger.Msg("Closing ViewManager - Main Menu.");
+
+ _viewManager.UiStateToggle(false);
+ }
+}
\ No newline at end of file