mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 14:29:25 +00:00
[DesktopVRSwitch] Minor changes
This commit is contained in:
parent
6d17085f21
commit
4c09f9bd57
25 changed files with 359 additions and 205 deletions
|
@ -1,2 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="BTKUILib">
|
||||
<HintPath>$(MsBuildThisFileDirectory)\..\.ManagedLibs\BTKUILib.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -3,6 +3,8 @@ 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 cohtml.Net;
|
||||
using HarmonyLib;
|
||||
using NAK.DesktopVRSwitch.Patches;
|
||||
using NAK.DesktopVRSwitch.VRModeTrackers;
|
||||
|
@ -117,13 +119,36 @@ internal class CVRPickupObjectPatches
|
|||
}
|
||||
}
|
||||
|
||||
internal class CohtmlUISystemPatches
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(UISystem), nameof(UISystem.RegisterGamepad))]
|
||||
[HarmonyPatch(typeof(UISystem), nameof(UISystem.UnregisterGamepad))]
|
||||
[HarmonyPatch(typeof(UISystem), nameof(UISystem.UpdateGamepadState))]
|
||||
private static bool Prefix_UISystem_FuckOff()
|
||||
{
|
||||
/**
|
||||
GameFace Version 1.34.0.4 – released 10 Nov 2022
|
||||
Fixed a crash when registering and unregistering gamepads
|
||||
Fix Fixed setting a gamepad object when creating GamepadEvent from JavaScript
|
||||
Fix Fixed a crash when unregistering a gamepad twice
|
||||
Fix Fixed a GamepadEvent related crash during garbage collector tracing
|
||||
|
||||
it is not fixed you fucking piece of shit
|
||||
**/
|
||||
|
||||
// dont
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal class SteamVRBehaviourPatches
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(SteamVR_Behaviour), nameof(SteamVR_Behaviour.OnQuit))]
|
||||
private static bool Prefix_SteamVR_Behaviour_OnQuit()
|
||||
{
|
||||
if (!DesktopVRSwitch.EntrySwitchToDesktopOnExit.Value)
|
||||
if (!ModSettings.EntrySwitchToDesktopOnExit.Value)
|
||||
return true;
|
||||
|
||||
// If we don't switch fast enough, SteamVR will force close.
|
||||
|
|
64
DesktopVRSwitch/Integrations/BTKUIAddon.cs
Normal file
64
DesktopVRSwitch/Integrations/BTKUIAddon.cs
Normal file
|
@ -0,0 +1,64 @@
|
|||
using BTKUILib;
|
||||
using BTKUILib.UIObjects;
|
||||
using System.Runtime.CompilerServices;
|
||||
using ABI_RC.Core.Base;
|
||||
|
||||
namespace NAK.DesktopVRSwitch.Integrations;
|
||||
|
||||
public static class BTKUIAddon
|
||||
{
|
||||
#region Initialization
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void Initialize()
|
||||
{
|
||||
// Add mod to the Misc Menu
|
||||
Page miscPage = QuickMenuAPI.MiscTabPage;
|
||||
Category vrSwitchMiscCategory = miscPage.AddCategory(ModSettings.SettingsCategory);
|
||||
|
||||
vrSwitchMiscCategory.AddButton("Switch VR Mode", "", "Switch to Desktop/VR.").OnPress +=
|
||||
() =>
|
||||
{
|
||||
QuickMenuAPI.ShowConfirm(
|
||||
title: "Switch VR Mode",
|
||||
content: "Are you sure you want to switch to Desktop/VR?",
|
||||
onYes: () => VRModeSwitchManager.Instance.AttemptSwitch()
|
||||
);
|
||||
};
|
||||
|
||||
SetupSwitchConfigurationPage(ref vrSwitchMiscCategory);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Pages Setup
|
||||
|
||||
private static void SetupSwitchConfigurationPage(ref Category parentCategory)
|
||||
{
|
||||
Page vrSwitchPage = parentCategory.AddPage("DesktopVRSwitch Settings", "", "Configure the settings for DesktopVRSwitch.", ModSettings.SettingsCategory);
|
||||
vrSwitchPage.MenuTitle = "DesktopVRSwitch Settings";
|
||||
Category vrSwitchCategory = vrSwitchPage.AddCategory(vrSwitchPage.MenuTitle);
|
||||
|
||||
AddMelonToggle(ref vrSwitchCategory, ModSettings.EntryEnterCalibrationOnSwitch);
|
||||
|
||||
AddMelonToggle(ref vrSwitchCategory, ModSettings.EntryUseTransitionOnSwitch);
|
||||
|
||||
AddMelonToggle(ref vrSwitchCategory, ModSettings.EntrySwitchToDesktopOnExit);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Melon Pref Helpers
|
||||
|
||||
private static void AddMelonToggle(ref Category category, MelonLoader.MelonPreferences_Entry<bool> entry)
|
||||
{
|
||||
category.AddToggle(entry.DisplayName, entry.Description, entry.Value).OnValueUpdated += b => entry.Value = b;
|
||||
}
|
||||
|
||||
private static void AddMelonSlider(ref Page page, MelonLoader.MelonPreferences_Entry<float> entry, float min, float max, int decimalPlaces = 2)
|
||||
{
|
||||
page.AddSlider(entry.DisplayName, entry.Description, entry.Value, min, max, decimalPlaces).OnValueUpdated += f => entry.Value = f;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
|
@ -9,21 +9,6 @@ public class DesktopVRSwitch : MelonMod
|
|||
{
|
||||
internal static MelonLogger.Instance Logger;
|
||||
|
||||
public static readonly MelonPreferences_Category Category =
|
||||
MelonPreferences.CreateCategory(nameof(DesktopVRSwitch));
|
||||
|
||||
public static readonly MelonPreferences_Entry<bool> 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<bool> EntryUseTransitionOnSwitch =
|
||||
Category.CreateEntry("Use Transition on Switch", true, description: "Should the world transition play on VRMode switch?");
|
||||
|
||||
//public static readonly MelonPreferences_Entry<bool> EntryRenderVRGameView =
|
||||
// Category.CreateEntry("Render VR Game View", true, description: "Should the VR view be displayed in the game window after VRMode switch?");
|
||||
|
||||
public static readonly MelonPreferences_Entry<bool> EntrySwitchToDesktopOnExit =
|
||||
Category.CreateEntry("Switch to Desktop on SteamVR Exit", false, description: "Should the game switch to Desktop when SteamVR quits?");
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
Logger = LoggerInstance;
|
||||
|
@ -41,8 +26,13 @@ public class DesktopVRSwitch : MelonMod
|
|||
// post processing fixes
|
||||
ApplyPatches(typeof(HarmonyPatches.CVRWorldPatches));
|
||||
|
||||
// fuck you
|
||||
ApplyPatches(typeof(HarmonyPatches.CohtmlUISystemPatches));
|
||||
|
||||
// prevent steamvr behaviour from closing game
|
||||
ApplyPatches(typeof(HarmonyPatches.SteamVRBehaviourPatches));
|
||||
|
||||
InitializeIntegration("BTKUILib", Integrations.BTKUIAddon.Initialize);
|
||||
}
|
||||
|
||||
public override void OnUpdate()
|
||||
|
@ -84,6 +74,15 @@ public class DesktopVRSwitch : MelonMod
|
|||
VRModeSwitchManager.RegisterVRModeTracker(new CVRWorldTracker());
|
||||
}
|
||||
|
||||
private static void InitializeIntegration(string modName, Action integrationAction)
|
||||
{
|
||||
if (RegisteredMelons.All(it => it.Info.Name != modName))
|
||||
return;
|
||||
|
||||
Logger.Msg($"Initializing {modName} integration.");
|
||||
integrationAction.Invoke();
|
||||
}
|
||||
|
||||
private void ApplyPatches(Type type)
|
||||
{
|
||||
try
|
||||
|
|
20
DesktopVRSwitch/ModSettings.cs
Normal file
20
DesktopVRSwitch/ModSettings.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using MelonLoader;
|
||||
|
||||
namespace NAK.DesktopVRSwitch;
|
||||
|
||||
public static class ModSettings
|
||||
{
|
||||
internal const string SettingsCategory = nameof(DesktopVRSwitch);
|
||||
|
||||
public static readonly MelonPreferences_Category Category =
|
||||
MelonPreferences.CreateCategory(SettingsCategory);
|
||||
|
||||
public static readonly MelonPreferences_Entry<bool> 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<bool> EntryUseTransitionOnSwitch =
|
||||
Category.CreateEntry("Use Transition on Switch", true, description: "Should the world transition play on VRMode switch?");
|
||||
|
||||
public static readonly MelonPreferences_Entry<bool> EntrySwitchToDesktopOnExit =
|
||||
Category.CreateEntry("Switch to Desktop on SteamVR Exit", false, description: "Should the game switch to Desktop when SteamVR quits?");
|
||||
}
|
|
@ -9,7 +9,7 @@ using UnityEngine.Rendering.PostProcessing;
|
|||
|
||||
namespace NAK.DesktopVRSwitch.Patches;
|
||||
|
||||
internal class ReferenceCameraPatch
|
||||
internal static class ReferenceCameraPatch
|
||||
{
|
||||
public static void OnWorldLoad()
|
||||
{
|
||||
|
@ -31,13 +31,15 @@ internal class ReferenceCameraPatch
|
|||
inactiveCam.depthTextureMode = activeCam.depthTextureMode;
|
||||
|
||||
// We cant copy this because we set it to 0 with ThirdPerson
|
||||
inactiveCam.cullingMask &= -32769;
|
||||
inactiveCam.cullingMask |= 256;
|
||||
inactiveCam.cullingMask |= 512;
|
||||
inactiveCam.cullingMask |= 32;
|
||||
inactiveCam.cullingMask &= -4097;
|
||||
inactiveCam.cullingMask |= 1024;
|
||||
inactiveCam.cullingMask |= 8192;
|
||||
var cullingMask = inactiveCam.cullingMask;
|
||||
cullingMask &= -32769;
|
||||
cullingMask |= 256;
|
||||
cullingMask |= 512;
|
||||
cullingMask |= 32;
|
||||
cullingMask &= -4097;
|
||||
cullingMask |= 1024;
|
||||
cullingMask |= 8192;
|
||||
inactiveCam.cullingMask = cullingMask;
|
||||
|
||||
// Copy post processing if added
|
||||
PostProcessLayer ppLayerActiveCam = activeCam.GetComponent<PostProcessLayer>();
|
||||
|
|
|
@ -2,47 +2,22 @@
|
|||
using NAK.DesktopVRSwitch.VRModeTrackers;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.XR;
|
||||
using UnityEngine.XR.Management;
|
||||
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;
|
||||
|
||||
public class VRModeSwitchManager : MonoBehaviour
|
||||
{
|
||||
#region Static
|
||||
|
||||
public static VRModeSwitchManager Instance { get; private set; }
|
||||
|
||||
// I don't think I *need* this. Only using cause I don't want stuff just existing.
|
||||
private static readonly List<VRModeTracker> _vrModeTrackers = new List<VRModeTracker>();
|
||||
public static void RegisterVRModeTracker(VRModeTracker observer) => observer.TrackerInit();
|
||||
public static void UnregisterVRModeTracker(VRModeTracker observer) => observer.TrackerDestroy();
|
||||
|
||||
public static event UnityAction<bool> OnPreVRModeSwitch;
|
||||
public static event UnityAction<bool> OnPostVRModeSwitch;
|
||||
public static event UnityAction<bool> OnFailVRModeSwitch;
|
||||
private const string XRSETTINGS_DEVICE = "OpenVR";
|
||||
#endregion
|
||||
|
||||
public static void RegisterVRModeTracker(VRModeTracker observer)
|
||||
{
|
||||
_vrModeTrackers.Add(observer);
|
||||
observer.TrackerInit();
|
||||
}
|
||||
|
||||
public static void UnregisterVRModeTracker(VRModeTracker observer)
|
||||
{
|
||||
_vrModeTrackers.Remove(observer);
|
||||
observer.TrackerDestroy();
|
||||
}
|
||||
#region Variables
|
||||
|
||||
// Settings
|
||||
public bool UseWorldTransition = true;
|
||||
|
@ -50,6 +25,10 @@ public class VRModeSwitchManager : MonoBehaviour
|
|||
|
||||
public bool SwitchInProgress { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity Methods
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null)
|
||||
|
@ -60,125 +39,120 @@ public class VRModeSwitchManager : MonoBehaviour
|
|||
Instance = this;
|
||||
}
|
||||
|
||||
public void AttemptSwitch()
|
||||
{
|
||||
StartCoroutine(StartSwitchCoroutine());
|
||||
}
|
||||
#endregion
|
||||
|
||||
private IEnumerator StartSwitchCoroutine()
|
||||
#region Public Methods
|
||||
|
||||
public static bool IsInXR() => XRGeneralSettings.Instance.Manager.activeLoader != null;
|
||||
|
||||
public void AttemptSwitch() => StartCoroutine(StartSwitchInternal());
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private IEnumerator StartSwitchInternal()
|
||||
{
|
||||
if (SwitchInProgress)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
SwitchInProgress = true;
|
||||
yield return null;
|
||||
|
||||
|
||||
if (UseWorldTransition)
|
||||
{ // start visual transition and wait for it to complete
|
||||
WorldTransitionSystem.Instance.StartTransition();
|
||||
yield return new WaitForSeconds(WorldTransitionSystem.Instance.CurrentInLength);
|
||||
}
|
||||
yield return StartCoroutine(StartTransition());
|
||||
|
||||
// Check if OpenVR is running
|
||||
bool isUsingVr = IsInXR();
|
||||
|
||||
InvokeOnPreSwitch(isUsingVr);
|
||||
|
||||
// Start switch
|
||||
if (!isUsingVr)
|
||||
yield return StartCoroutine(StartXR());
|
||||
else
|
||||
StopXR();
|
||||
yield return StartCoroutine(XRAndReloadAvatar(!isUsingVr));
|
||||
|
||||
// Check for updated VR mode
|
||||
if (isUsingVr != IsInXR())
|
||||
if (UseWorldTransition)
|
||||
yield return StartCoroutine(ContinueTransition());
|
||||
|
||||
SwitchInProgress = false;
|
||||
}
|
||||
|
||||
private IEnumerator XRAndReloadAvatar(bool start)
|
||||
{
|
||||
// reload the local avatar
|
||||
if (ReloadLocalAvatar)
|
||||
yield return StartCoroutine(start ? XRHandler.StartXR() : XRHandler.StopXR());
|
||||
|
||||
bool isUsingVr = IsInXR();
|
||||
if (isUsingVr == start)
|
||||
{
|
||||
ReloadAvatar();
|
||||
InvokeOnPostSwitch(start);
|
||||
}
|
||||
else
|
||||
{
|
||||
InvokeOnFailedSwitch(start);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReloadAvatar()
|
||||
{
|
||||
if (!ReloadLocalAvatar)
|
||||
return;
|
||||
|
||||
Utils.ClearLocalAvatar();
|
||||
Utils.ReloadLocalAvatar();
|
||||
}
|
||||
|
||||
InvokeOnPostSwitch(!isUsingVr);
|
||||
}
|
||||
else
|
||||
#endregion
|
||||
|
||||
#region Transition Coroutines
|
||||
|
||||
private IEnumerator StartTransition()
|
||||
{
|
||||
InvokeOnFailedSwitch(!isUsingVr);
|
||||
if (WorldTransitionSystem.Instance == null) yield break;
|
||||
WorldTransitionSystem.Instance.StartTransition();
|
||||
yield return new WaitForSeconds(WorldTransitionSystem.Instance.CurrentInLength);
|
||||
}
|
||||
|
||||
if (UseWorldTransition)
|
||||
{ // would be cool to have out length
|
||||
private IEnumerator ContinueTransition()
|
||||
{
|
||||
if (WorldTransitionSystem.Instance == null) yield break;
|
||||
WorldTransitionSystem.Instance.ContinueTransition();
|
||||
yield return new WaitForSeconds(WorldTransitionSystem.Instance.CurrentInLength);
|
||||
}
|
||||
|
||||
SwitchInProgress = false;
|
||||
yield break;
|
||||
#endregion
|
||||
|
||||
#region Event Handling
|
||||
|
||||
public class VRModeEventArgs : EventArgs
|
||||
{
|
||||
public bool IsUsingVr { get; }
|
||||
public Camera PlayerCamera { get; }
|
||||
|
||||
public VRModeEventArgs(bool isUsingVr, Camera playerCamera)
|
||||
{
|
||||
IsUsingVr = isUsingVr;
|
||||
PlayerCamera = playerCamera;
|
||||
}
|
||||
}
|
||||
|
||||
private void SafeInvokeUnityEvent(UnityAction<bool> switchEvent, bool isUsingVr)
|
||||
public static event EventHandler<VRModeEventArgs> OnPreVRModeSwitch;
|
||||
public static event EventHandler<VRModeEventArgs> OnPostVRModeSwitch;
|
||||
public static event EventHandler<VRModeEventArgs> OnFailVRModeSwitch;
|
||||
|
||||
private void InvokeOnPreSwitch(bool isUsingVr) => SafeInvokeUnityEvent(OnPreVRModeSwitch, isUsingVr);
|
||||
private void InvokeOnPostSwitch(bool isUsingVr) => SafeInvokeUnityEvent(OnPostVRModeSwitch, isUsingVr);
|
||||
private void InvokeOnFailedSwitch(bool isUsingVr) => SafeInvokeUnityEvent(OnFailVRModeSwitch, isUsingVr);
|
||||
|
||||
private void SafeInvokeUnityEvent(EventHandler<VRModeEventArgs> switchEvent, bool isUsingVr)
|
||||
{
|
||||
try
|
||||
{
|
||||
switchEvent.Invoke(isUsingVr);
|
||||
var playerCamera = Utils.GetPlayerCameraObject(isUsingVr).GetComponent<Camera>();
|
||||
switchEvent?.Invoke(this, new VRModeEventArgs(isUsingVr, playerCamera));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"Error in event handler: {e}");
|
||||
DesktopVRSwitch.Logger.Error($"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 IsInXR() => XRGeneralSettings.Instance.Manager.activeLoader != null;
|
||||
|
||||
private IEnumerator StartXR()
|
||||
{
|
||||
yield return null; // wait a frame before checking
|
||||
yield return XRGeneralSettings.Instance.Manager.InitializeLoader();
|
||||
|
||||
if (XRGeneralSettings.Instance.Manager.activeLoader != null)
|
||||
{
|
||||
XRGeneralSettings.Instance.Manager.StartSubsystems();
|
||||
}
|
||||
|
||||
yield return null;
|
||||
yield break;
|
||||
}
|
||||
|
||||
private void StopXR()
|
||||
{
|
||||
if (!XRGeneralSettings.Instance.Manager.isInitializationComplete)
|
||||
return;
|
||||
|
||||
// Forces SteamVR to reinitialize SteamVR_Input next switch
|
||||
SteamVR_ActionSet_Manager.DisableAllActionSets();
|
||||
SteamVR_Input.initialized = false;
|
||||
|
||||
// Remove SteamVR behaviour & render
|
||||
DestroyImmediate(SteamVR_Behaviour.instance.gameObject);
|
||||
SteamVR.enabled = false; // disposes SteamVR
|
||||
|
||||
// Disable UnityXR
|
||||
XRGeneralSettings.Instance.Manager.StopSubsystems();
|
||||
XRGeneralSettings.Instance.Manager.DeinitializeLoader();
|
||||
|
||||
// We don't really need to wait a frame on Stop()
|
||||
}
|
||||
#endregion
|
||||
}
|
|
@ -15,10 +15,10 @@ public class CVRGestureRecognizerTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg("Updating CVRGestureRecognizer _camera to active camera.");
|
||||
|
||||
CVRGestureRecognizer.Instance._camera = Utils.GetPlayerCameraObject(intoVR).GetComponent<Camera>();
|
||||
CVRGestureRecognizer.Instance._camera = args.PlayerCamera;
|
||||
}
|
||||
}
|
|
@ -16,14 +16,14 @@ public class CVRInputManagerTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg("Resetting CVRInputManager inputs.");
|
||||
|
||||
CVRInputManager.Instance.inputEnabled = true;
|
||||
|
||||
// IM CRYING
|
||||
CVRInputManager.Instance.reload = true;
|
||||
//CVRInputManager.Instance.reload = true;
|
||||
|
||||
//just in case
|
||||
CVRInputManager.Instance.textInputFocused = false;
|
||||
|
@ -42,6 +42,6 @@ public class CVRInputManagerTracker : VRModeTracker
|
|||
CVRInputManager.Instance.AddInputModule(CVRInputManager._moduleXR = new CVRInputModule_XR());
|
||||
|
||||
//enable xr input or whatnot
|
||||
CVRInputManager._moduleXR.InputEnabled = intoVR;
|
||||
CVRInputManager._moduleXR.InputEnabled = args.IsUsingVr;
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ public class CVRPickupObjectTracker : MonoBehaviour
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
public void OnPostSwitch(bool intoVR)
|
||||
public void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
if (_pickupObject != null)
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@ public class CVRWorldTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg("Configuring CVRWorld. Updating PostProcessing & DesktopCameraController FOV settings.");
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@ public class CVR_InteractableManagerTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg($"Setting CVRInputManager inputEnabled & CVR_InteractableManager enableInteractions to {!intoVR}");
|
||||
DesktopVRSwitch.Logger.Msg($"Setting CVRInputManager inputEnabled & CVR_InteractableManager enableInteractions to {!args.IsUsingVr}");
|
||||
|
||||
CVR_InteractableManager.enableInteractions = !intoVR;
|
||||
CVR_InteractableManager.enableInteractions = !args.IsUsingVr;
|
||||
}
|
||||
}
|
|
@ -17,18 +17,18 @@ public class CVR_MenuManagerTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPreSwitch(bool intoVR)
|
||||
private void OnPreSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg("Closing CVR_MenuManager - Quick Menu.");
|
||||
|
||||
CVR_MenuManager.Instance.ToggleQuickMenu(false);
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg("Updating CVR_Menu_Data core data.");
|
||||
|
||||
CVR_MenuManager.Instance.coreData.core.inVr = intoVR;
|
||||
CVR_MenuManager.Instance.coreData.core.inVr = args.IsUsingVr;
|
||||
CVR_MenuManager.Instance.quickMenu.transform.localPosition = Vector3.zero;
|
||||
CVR_MenuManager.Instance.quickMenu.transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,8 @@ public class CameraFacingObjectTracker : MonoBehaviour
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
public void OnPostSwitch(bool intoVR)
|
||||
public void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
// TODO: cache camera
|
||||
_cameraFacingObject.m_Camera = Utils.GetPlayerCameraObject(intoVR).GetComponent<Camera>();
|
||||
_cameraFacingObject.m_Camera = args.PlayerCamera;
|
||||
}
|
||||
}
|
|
@ -14,8 +14,8 @@ public class CheckVRTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
CheckVR.Instance.hasVrDeviceLoaded = intoVR;
|
||||
CheckVR.Instance.hasVrDeviceLoaded = args.IsUsingVr;
|
||||
}
|
||||
}
|
|
@ -16,11 +16,11 @@ public class CohtmlHudTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg("Configuring new hud affinity for CohtmlHud.");
|
||||
|
||||
CohtmlHud.Instance.gameObject.transform.parent = Utils.GetPlayerCameraObject(intoVR).transform;
|
||||
CohtmlHud.Instance.gameObject.transform.parent = Utils.GetPlayerCameraObject(args.IsUsingVr).transform;
|
||||
// This handles rotation and position
|
||||
CVRTools.ConfigureHudAffinity();
|
||||
CohtmlHud.Instance.gameObject.transform.localScale = new Vector3(1.2f, 1f, 1.2f);
|
||||
|
|
|
@ -14,11 +14,11 @@ public class HudOperationsTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg("Switching HudOperations worldLoadingItem & worldLoadStatus.");
|
||||
|
||||
HudOperations.Instance.worldLoadingItem = intoVR ? HudOperations.Instance.worldLoadingItemVr : HudOperations.Instance.worldLoadingItemDesktop;
|
||||
HudOperations.Instance.worldLoadStatus = intoVR ? HudOperations.Instance.worldLoadStatusVr : HudOperations.Instance.worldLoadStatusDesktop;
|
||||
HudOperations.Instance.worldLoadingItem = args.IsUsingVr ? HudOperations.Instance.worldLoadingItemVr : HudOperations.Instance.worldLoadingItemDesktop;
|
||||
HudOperations.Instance.worldLoadStatus = args.IsUsingVr ? HudOperations.Instance.worldLoadStatusVr : HudOperations.Instance.worldLoadStatusDesktop;
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ public class IKSystemTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPreSwitch(bool intoVR)
|
||||
private void OnPreSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
BodySystem.TrackingEnabled = false;
|
||||
BodySystem.TrackingPositionWeight = 0f;
|
||||
|
@ -30,7 +30,7 @@ public class IKSystemTracker : VRModeTracker
|
|||
IKSystem.vrik.enabled = false;
|
||||
}
|
||||
|
||||
private void OnFailedSwitch(bool intoVR)
|
||||
private void OnFailedSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
BodySystem.TrackingEnabled = true;
|
||||
BodySystem.TrackingPositionWeight = 1f;
|
||||
|
@ -40,7 +40,7 @@ public class IKSystemTracker : VRModeTracker
|
|||
IKSystem.vrik.enabled = true;
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
if (IKSystem.vrik != null)
|
||||
UnityEngine.Object.DestroyImmediate(IKSystem.vrik);
|
||||
|
@ -54,12 +54,12 @@ public class IKSystemTracker : VRModeTracker
|
|||
BodySystem.isRecalibration = false;
|
||||
|
||||
// Make it so you don't instantly end up in FBT from Desktop
|
||||
IKSystem.firstAvatarLoaded = DesktopVRSwitch.EntryEnterCalibrationOnSwitch.Value;
|
||||
IKSystem.firstAvatarLoaded = ModSettings.EntryEnterCalibrationOnSwitch.Value;
|
||||
|
||||
// Turn off finger tracking just in case the user switched controllers
|
||||
IKSystem.Instance.FingerSystem.controlActive = false;
|
||||
|
||||
SetupSteamVRTrackingModule(intoVR);
|
||||
SetupSteamVRTrackingModule(args.IsUsingVr);
|
||||
}
|
||||
|
||||
private void SetupSteamVRTrackingModule(bool enableVR)
|
||||
|
@ -69,14 +69,10 @@ public class IKSystemTracker : VRModeTracker
|
|||
if (openVRModule != null)
|
||||
{
|
||||
if (enableVR)
|
||||
{
|
||||
openVRModule.ModuleStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
openVRModule.ModuleDestroy();
|
||||
}
|
||||
}
|
||||
else if (enableVR)
|
||||
{
|
||||
var newVRModule = new SteamVRTrackingModule();
|
||||
|
|
|
@ -17,16 +17,16 @@ public class MetaPortTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg($"Setting MetaPort isUsingVr to {intoVR}.");
|
||||
DesktopVRSwitch.Logger.Msg($"Setting MetaPort isUsingVr to {args.IsUsingVr}.");
|
||||
|
||||
// Main thing most of the game checks for if using VR
|
||||
MetaPort.Instance.isUsingVr = intoVR;
|
||||
MetaPort.Instance.isUsingVr = args.IsUsingVr;
|
||||
|
||||
// replace
|
||||
UpdateRichPresence();
|
||||
ResetSteamVROverrides(intoVR);
|
||||
ResetSteamVROverrides(args.IsUsingVr);
|
||||
}
|
||||
|
||||
private void UpdateRichPresence()
|
||||
|
|
|
@ -23,7 +23,7 @@ public class MovementSystemTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPreSwitch(bool intoVR)
|
||||
private void OnPreSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
|
||||
DesktopVRSwitch.Logger.Msg("Storing player world position and rotation.");
|
||||
|
@ -39,17 +39,17 @@ public class MovementSystemTracker : VRModeTracker
|
|||
|
||||
}
|
||||
|
||||
private void OnFailedSwitch(bool intoVR)
|
||||
private void OnFailedSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg("Resetting MovementSystem mobility.");
|
||||
|
||||
MovementSystem.Instance.SetImmobilized(false);
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
// Lazy
|
||||
MelonLoader.MelonCoroutines.Start(TeleportFrameAfter(intoVR));
|
||||
MelonLoader.MelonCoroutines.Start(TeleportFrameAfter(args.IsUsingVr));
|
||||
}
|
||||
|
||||
private IEnumerator TeleportFrameAfter(bool intoVR)
|
||||
|
|
|
@ -14,11 +14,11 @@ public class PlayerSetupTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg("Switching active PlayerSetup camera rigs. Updating Desktop camera FOV.");
|
||||
|
||||
PlayerSetup.Instance.desktopCameraRig.SetActive(!intoVR);
|
||||
PlayerSetup.Instance.vrCameraRig.SetActive(intoVR);
|
||||
PlayerSetup.Instance.desktopCameraRig.SetActive(!args.IsUsingVr);
|
||||
PlayerSetup.Instance.vrCameraRig.SetActive(args.IsUsingVr);
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ public class PortableCameraTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPostVRModeSwitch -= OnPostSwitch;
|
||||
}
|
||||
|
||||
private void OnPostSwitch(bool intoVR)
|
||||
private void OnPostSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg("Forcing PortableCamera canvas mirroring off.");
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace NAK.DesktopVRSwitch.VRModeTrackers;
|
||||
|
||||
public class VRModeTracker
|
||||
public abstract class VRModeTracker
|
||||
{
|
||||
public virtual void TrackerInit() { }
|
||||
public virtual void TrackerDestroy() { }
|
||||
|
|
|
@ -14,7 +14,7 @@ public class ViewManagerTracker : VRModeTracker
|
|||
VRModeSwitchManager.OnPreVRModeSwitch -= OnPreSwitch;
|
||||
}
|
||||
|
||||
private void OnPreSwitch(bool intoVR)
|
||||
private void OnPreSwitch(object sender, VRModeSwitchManager.VRModeEventArgs args)
|
||||
{
|
||||
DesktopVRSwitch.Logger.Msg("Closing ViewManager - Main Menu.");
|
||||
|
||||
|
|
66
DesktopVRSwitch/XRHandler.cs
Normal file
66
DesktopVRSwitch/XRHandler.cs
Normal file
|
@ -0,0 +1,66 @@
|
|||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using ABI_RC.Core.Savior;
|
||||
using Unity.XR.OpenVR;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Management;
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using Valve.VR;
|
||||
|
||||
namespace NAK.DesktopVRSwitch;
|
||||
|
||||
internal static class XRHandler
|
||||
{
|
||||
internal static IEnumerator StartXR()
|
||||
{
|
||||
yield return XRGeneralSettings.Instance.Manager.InitializeLoader();
|
||||
|
||||
if (XRGeneralSettings.Instance.Manager.activeLoader != null)
|
||||
XRGeneralSettings.Instance.Manager.StartSubsystems();
|
||||
else
|
||||
StopXR();
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
internal static IEnumerator StopXR()
|
||||
{
|
||||
if (!XRGeneralSettings.Instance.Manager.isInitializationComplete)
|
||||
yield break;
|
||||
|
||||
// Forces SteamVR to reinitialize SteamVR_Input next switch
|
||||
SteamVR_ActionSet_Manager.DisableAllActionSets();
|
||||
SteamVR_Input.initialized = false;
|
||||
|
||||
// Remove SteamVR behaviour & render
|
||||
UnityEngine.Object.DestroyImmediate(SteamVR_Behaviour.instance.gameObject);
|
||||
SteamVR.enabled = false; // disposes SteamVR
|
||||
|
||||
// Disable UnityXR
|
||||
XRGeneralSettings.Instance.Manager.StopSubsystems();
|
||||
XRGeneralSettings.Instance.Manager.DeinitializeLoader();
|
||||
|
||||
// We don't really need to wait a frame on Stop()
|
||||
yield return null;
|
||||
}
|
||||
|
||||
internal static void SwitchLoader()
|
||||
{
|
||||
XRLoader item;
|
||||
|
||||
if (!CheckVR.Instance.forceOpenXr)
|
||||
{
|
||||
item = ScriptableObject.CreateInstance<OpenVRLoader>();
|
||||
DesktopVRSwitch.Logger.Msg("Using XR Loader: SteamVR");
|
||||
}
|
||||
else
|
||||
{
|
||||
item = ScriptableObject.CreateInstance<OpenXRLoader>();
|
||||
DesktopVRSwitch.Logger.Msg("Using XR Loader: OpenXR");
|
||||
}
|
||||
|
||||
typeof(XRManagerSettings)
|
||||
.GetField("m_Loaders", BindingFlags.Instance | BindingFlags.NonPublic)
|
||||
?.SetValue(XRGeneralSettings.Instance.Manager, new List<XRLoader> { item });
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue