mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-01 13:59:22 +00:00
Merge remote-tracking branch 'DesktopVRSwitch/cvr-stable-openvr'
Merge DesktopVRSwitch
This commit is contained in:
commit
6b313bc7bd
16 changed files with 1035 additions and 18 deletions
141
DesktopVRSwitch/DesktopVRSwitch.cs
Normal file
141
DesktopVRSwitch/DesktopVRSwitch.cs
Normal file
|
@ -0,0 +1,141 @@
|
|||
using NAK.Melons.DesktopVRSwitch.Patches;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR;
|
||||
using Valve.VR;
|
||||
|
||||
namespace NAK.Melons.DesktopVRSwitch;
|
||||
|
||||
public class DesktopVRSwitch : MonoBehaviour
|
||||
{
|
||||
//Debug Settings
|
||||
public bool _reloadLocalAvatar = true;
|
||||
public bool _softVRSwitch = false;
|
||||
|
||||
//Internal Stuff
|
||||
private bool _switchInProgress = false;
|
||||
|
||||
void Start()
|
||||
{
|
||||
//do not pause game, this breaks dynbones & trackers
|
||||
SteamVR_Settings.instance.pauseGameWhenDashboardVisible = false;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.F6) && Input.GetKey(KeyCode.LeftControl))
|
||||
{
|
||||
SwitchVRMode();
|
||||
}
|
||||
}
|
||||
|
||||
public void SwitchVRMode()
|
||||
{
|
||||
if (_switchInProgress) return;
|
||||
if (!IsInVR())
|
||||
{
|
||||
StartCoroutine(StartVRSystem());
|
||||
}
|
||||
else
|
||||
{
|
||||
StartCoroutine(StopVR());
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsInVR() => XRSettings.enabled;
|
||||
|
||||
private IEnumerator StartVRSystem()
|
||||
{
|
||||
|
||||
PreVRModeSwitch(true);
|
||||
XRSettings.LoadDeviceByName("OpenVR");
|
||||
yield return null; //wait a frame before checking
|
||||
if (!string.IsNullOrEmpty(XRSettings.loadedDeviceName))
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg("Starting SteamVR...");
|
||||
XRSettings.enabled = true;
|
||||
//force steamvr to reinitialize input
|
||||
//this does SteamVR_Input.actionSets[0].Activate() for us (we deactivate in StopVR())
|
||||
//but only if SteamVR_Settings.instance.activateFirstActionSetOnStart is enabled
|
||||
//which in ChilloutVR, it is, because all those settings are default
|
||||
SteamVR_Input.Initialize(true);
|
||||
yield return null;
|
||||
PostVRModeSwitch(true);
|
||||
yield break;
|
||||
}
|
||||
DesktopVRSwitchMod.Logger.Error("Initializing VR Failed. Is there no VR device connected?");
|
||||
FailedVRModeSwitch(true);
|
||||
yield break;
|
||||
}
|
||||
|
||||
private IEnumerator StopVR()
|
||||
{
|
||||
PreVRModeSwitch(false);
|
||||
yield return null;
|
||||
if (!string.IsNullOrEmpty(XRSettings.loadedDeviceName))
|
||||
{
|
||||
//SteamVR.SafeDispose(); //might fuck with SteamVRTrackingModule
|
||||
//deactivate the action set so SteamVR_Input.Initialize can reactivate
|
||||
SteamVR_Input.actionSets[0].Deactivate(SteamVR_Input_Sources.Any);
|
||||
XRSettings.LoadDeviceByName("");
|
||||
XRSettings.enabled = false;
|
||||
yield return null;
|
||||
Time.fixedDeltaTime = 0.02f; //reset physics time to Desktop default
|
||||
PostVRModeSwitch(false);
|
||||
yield break;
|
||||
}
|
||||
DesktopVRSwitchMod.Logger.Error("Attempted to exit VR without a VR device loaded.");
|
||||
FailedVRModeSwitch(false);
|
||||
yield break;
|
||||
}
|
||||
|
||||
//one frame after switch attempt
|
||||
public void FailedVRModeSwitch(bool isVR)
|
||||
{
|
||||
if (_softVRSwitch) return;
|
||||
//let tracked objects know a switch failed
|
||||
VRModeSwitchTracker.FailVRModeSwitch(isVR);
|
||||
}
|
||||
|
||||
//one frame before switch attempt
|
||||
public void PreVRModeSwitch(bool isVR)
|
||||
{
|
||||
if (_softVRSwitch) return;
|
||||
//let tracked objects know we are attempting to switch
|
||||
VRModeSwitchTracker.PreVRModeSwitch(isVR);
|
||||
}
|
||||
|
||||
//one frame after switch attempt
|
||||
public void PostVRModeSwitch(bool isVR)
|
||||
{
|
||||
if (_softVRSwitch) return;
|
||||
//close the menus
|
||||
TryCatchHell.CloseCohtmlMenus();
|
||||
|
||||
//the base of VR checks
|
||||
TryCatchHell.SetCheckVR(isVR);
|
||||
TryCatchHell.SetMetaPort(isVR);
|
||||
|
||||
//game basics for functional gameplay post switch
|
||||
TryCatchHell.RepositionCohtmlHud(isVR);
|
||||
TryCatchHell.UpdateHudOperations(isVR);
|
||||
TryCatchHell.DisableMirrorCanvas();
|
||||
TryCatchHell.SwitchActiveCameraRigs(isVR);
|
||||
TryCatchHell.ResetCVRInputManager();
|
||||
TryCatchHell.UpdateRichPresence();
|
||||
TryCatchHell.UpdateGestureReconizerCam();
|
||||
TryCatchHell.UpdateMenuCoreData(isVR);
|
||||
|
||||
//let tracked objects know we switched
|
||||
VRModeSwitchTracker.PostVRModeSwitch(isVR);
|
||||
|
||||
//reload avatar by default, optional for debugging
|
||||
if (_reloadLocalAvatar)
|
||||
{
|
||||
TryCatchHell.ReloadLocalAvatar();
|
||||
}
|
||||
|
||||
_switchInProgress = false;
|
||||
}
|
||||
}
|
||||
|
73
DesktopVRSwitch/DesktopVRSwitch.csproj
Normal file
73
DesktopVRSwitch/DesktopVRSwitch.csproj
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="0Harmony">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\0Harmony.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp-firstpass">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Aura2_Core">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Aura2_Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="cohtml.Net">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Cohtml.Runtime">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MelonLoader">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SteamVR">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\SteamVR.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UIExpansionKit">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\UIExpansionKit.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Postprocessing.Runtime">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Unity.Postprocessing.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TextMeshPro">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Unity.TextMeshPro.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VRModule">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.VRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VRModule">
|
||||
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.VRModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.XRModule">
|
||||
<HintPath>..\..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.XRModule.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="Deploy" AfterTargets="Build">
|
||||
<Copy SourceFiles="$(TargetPath)" DestinationFolder="C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\" />
|
||||
<Message Text="Copied $(TargetPath) to C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\" Importance="high" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
25
DesktopVRSwitch/DesktopVRSwitch.sln
Normal file
25
DesktopVRSwitch/DesktopVRSwitch.sln
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.2.32630.192
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesktopVRSwitch", "DesktopVRSwitch.csproj", "{4008E6D1-32F9-449B-8820-80ACF0ED8233}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4008E6D1-32F9-449B-8820-80ACF0ED8233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4008E6D1-32F9-449B-8820-80ACF0ED8233}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4008E6D1-32F9-449B-8820-80ACF0ED8233}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4008E6D1-32F9-449B-8820-80ACF0ED8233}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {9F6A1F88-B3D1-46F3-9370-9DDAE1F707C3}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
120
DesktopVRSwitch/HarmonyPatches.cs
Normal file
120
DesktopVRSwitch/HarmonyPatches.cs
Normal file
|
@ -0,0 +1,120 @@
|
|||
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.Melons.DesktopVRSwitch.Patches;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.Melons.DesktopVRSwitch.HarmonyPatches;
|
||||
|
||||
internal class PlayerSetupPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlayerSetup), "Start")]
|
||||
private static void Postfix_PlayerSetup_Start(ref PlayerSetup __instance)
|
||||
{
|
||||
if (CheckVR.Instance != null)
|
||||
{
|
||||
CheckVR.Instance.gameObject.AddComponent<DesktopVRSwitch>();
|
||||
return;
|
||||
}
|
||||
__instance.gameObject.AddComponent<DesktopVRSwitch>();
|
||||
DesktopVRSwitchMod.Logger.Error("CheckVR not found. Reverting to fallback method. This should never happen!");
|
||||
}
|
||||
}
|
||||
|
||||
internal class MovementSystemPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(MovementSystem), "Start")]
|
||||
private static void Postfix_MovementSystem_Start(ref MovementSystem __instance)
|
||||
{
|
||||
__instance.gameObject.AddComponent<MovementSystemTracker>();
|
||||
}
|
||||
}
|
||||
|
||||
internal class CVRPickupObjectPatches
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(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<CVRPickupObjectTracker>();
|
||||
tracker.pickupObject = __instance;
|
||||
tracker.storedGripOrigin = (!MetaPort.Instance.isUsingVr ? vrOrigin : desktopOrigin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class CVRWorldPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(CVRWorld), "SetDefaultCamValues")]
|
||||
private static void CVRWorld_SetDefaultCamValues_Postfix()
|
||||
{
|
||||
ReferenceCameraPatch.OnWorldLoad();
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(CVRWorld), "CopyRefCamValues")]
|
||||
private static void CVRWorld_CopyRefCamValues_Postfix()
|
||||
{
|
||||
ReferenceCameraPatch.OnWorldLoad();
|
||||
}
|
||||
}
|
||||
|
||||
internal class CameraFacingObjectPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(CameraFacingObject), "Start")]
|
||||
private static void Postfix_CameraFacingObject_Start(ref CameraFacingObject __instance)
|
||||
{
|
||||
__instance.gameObject.AddComponent<CameraFacingObjectTracker>();
|
||||
}
|
||||
}
|
||||
|
||||
internal class IKSystemPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(IKSystem), "Start")]
|
||||
private static void Postfix_IKSystem_Start(ref IKSystem __instance)
|
||||
{
|
||||
__instance.gameObject.AddComponent<IKSystemTracker>();
|
||||
}
|
||||
|
||||
[HarmonyPostfix] //lazy fix so i dont need to wait few frames
|
||||
[HarmonyPatch(typeof(TrackingPoint), "Initialize")]
|
||||
private 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), "ModuleDestroy")]
|
||||
private static void Postfix_SteamVRTrackingModule_ModuleDestroy(ref SteamVRTrackingModule __instance)
|
||||
{
|
||||
for (int i = 0; i < __instance.TrackingPoints.Count; i++)
|
||||
{
|
||||
UnityEngine.Object.Destroy(__instance.TrackingPoints[i].referenceGameObject);
|
||||
}
|
||||
__instance.TrackingPoints.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
internal class VRTrackerManagerPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(VRTrackerManager), "Start")]
|
||||
private static void Postfix_VRTrackerManager_Start(ref VRTrackerManager __instance)
|
||||
{
|
||||
__instance.gameObject.AddComponent<VRTrackerManagerTracker>();
|
||||
}
|
||||
}
|
54
DesktopVRSwitch/Main.cs
Normal file
54
DesktopVRSwitch/Main.cs
Normal file
|
@ -0,0 +1,54 @@
|
|||
using MelonLoader;
|
||||
|
||||
/**
|
||||
I know the TryCatchHell thing might be a bit exessive, but it is
|
||||
built so if a user that happens to have access to a build I do not,
|
||||
I will have a good idea of what broke and where, and what to look out
|
||||
for when updates/experimentals release. (which has happened a few times)
|
||||
|
||||
It is also just in case other mods break or tweak functionality that
|
||||
could fuck with switching. Or if they try to detect switching and break...
|
||||
|
||||
The VRModeSwitchTracker system is also built so I can easily & quickly make adjustments to
|
||||
components that may or may not change between builds without breaking the rest of the mod.
|
||||
**/
|
||||
|
||||
namespace NAK.Melons.DesktopVRSwitch;
|
||||
|
||||
public class DesktopVRSwitchMod : MelonMod
|
||||
{
|
||||
internal const string SettingsCategory = "DesktopVRSwitch";
|
||||
internal static MelonPreferences_Category mCategory;
|
||||
internal static MelonLogger.Instance Logger;
|
||||
|
||||
internal static MelonPreferences_Entry<bool>
|
||||
mSetting_EnterCalibrationOnSwitch;
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
Logger = LoggerInstance;
|
||||
mCategory = MelonPreferences.CreateCategory(SettingsCategory);
|
||||
mSetting_EnterCalibrationOnSwitch = mCategory.CreateEntry<bool>("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.");
|
||||
|
||||
ApplyPatches(typeof(HarmonyPatches.PlayerSetupPatches));
|
||||
ApplyPatches(typeof(HarmonyPatches.CVRPickupObjectPatches));
|
||||
ApplyPatches(typeof(HarmonyPatches.CVRWorldPatches));
|
||||
ApplyPatches(typeof(HarmonyPatches.CameraFacingObjectPatches));
|
||||
ApplyPatches(typeof(HarmonyPatches.IKSystemPatches));
|
||||
ApplyPatches(typeof(HarmonyPatches.MovementSystemPatches));
|
||||
ApplyPatches(typeof(HarmonyPatches.VRTrackerManagerPatches));
|
||||
}
|
||||
|
||||
private void ApplyPatches(Type type)
|
||||
{
|
||||
try
|
||||
{
|
||||
HarmonyInstance.PatchAll(type);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Msg($"Failed while patching {type.Name}!");
|
||||
Logger.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
31
DesktopVRSwitch/Patches/CVRPickupObjectTracker.cs
Normal file
31
DesktopVRSwitch/Patches/CVRPickupObjectTracker.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using ABI.CCK.Components;
|
||||
using UnityEngine;
|
||||
|
||||
//Thanks Ben! I was scared of transpiler so I reworked a bit...
|
||||
|
||||
namespace NAK.Melons.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 isVR, Camera activeCamera)
|
||||
{
|
||||
if (pickupObject != null)
|
||||
{
|
||||
if (pickupObject._controllerRay != null) pickupObject._controllerRay.DropObject(true);
|
||||
(storedGripOrigin, pickupObject.gripOrigin) = (pickupObject.gripOrigin, storedGripOrigin);
|
||||
}
|
||||
}
|
||||
}
|
24
DesktopVRSwitch/Patches/CameraFacingObjectTracker.cs
Normal file
24
DesktopVRSwitch/Patches/CameraFacingObjectTracker.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using ABI_RC.Core.Util.Object_Behaviour;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.Melons.DesktopVRSwitch.Patches;
|
||||
|
||||
public class CameraFacingObjectTracker : MonoBehaviour
|
||||
{
|
||||
public CameraFacingObject cameraFacingObject;
|
||||
void Start()
|
||||
{
|
||||
cameraFacingObject = GetComponent<CameraFacingObject>();
|
||||
VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
|
||||
}
|
||||
|
||||
public void PostVRModeSwitch(bool isVR, Camera activeCamera)
|
||||
{
|
||||
cameraFacingObject.m_Camera = activeCamera;
|
||||
}
|
||||
}
|
61
DesktopVRSwitch/Patches/IKSystemTracker.cs
Normal file
61
DesktopVRSwitch/Patches/IKSystemTracker.cs
Normal file
|
@ -0,0 +1,61 @@
|
|||
using ABI_RC.Systems.IK;
|
||||
using ABI_RC.Systems.IK.TrackingModules;
|
||||
using HarmonyLib;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.Melons.DesktopVRSwitch.Patches;
|
||||
|
||||
public class IKSystemTracker : MonoBehaviour
|
||||
{
|
||||
public IKSystem ikSystem;
|
||||
public Traverse _traverseModules;
|
||||
|
||||
void Start()
|
||||
{
|
||||
ikSystem = GetComponent<IKSystem>();
|
||||
_traverseModules = Traverse.Create(ikSystem).Field("_trackingModules");
|
||||
VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
|
||||
}
|
||||
|
||||
public void PostVRModeSwitch(bool isVR, Camera activeCamera)
|
||||
{
|
||||
var _trackingModules = _traverseModules.GetValue<List<TrackingModule>>();
|
||||
SteamVRTrackingModule openVRTrackingModule = _trackingModules.FirstOrDefault(m => m is SteamVRTrackingModule) as SteamVRTrackingModule;
|
||||
if (openVRTrackingModule != null)
|
||||
{
|
||||
if (isVR)
|
||||
{
|
||||
openVRTrackingModule.ModuleStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
//why named destroy when it doesnt ?
|
||||
openVRTrackingModule.ModuleDestroy();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var steamVRTrackingModule = CreateSteamVRTrackingModule();
|
||||
ikSystem.AddTrackingModule(steamVRTrackingModule);
|
||||
}
|
||||
|
||||
//make it so you dont instantly end up in FBT from Desktop
|
||||
IKSystem.firstAvatarLoaded = DesktopVRSwitchMod.mSetting_EnterCalibrationOnSwitch.Value;
|
||||
//turn of finger tracking just in case user switched controllers
|
||||
ikSystem.FingerSystem.controlActive = false;
|
||||
}
|
||||
|
||||
//thanks for marking the constructor as internal
|
||||
private SteamVRTrackingModule CreateSteamVRTrackingModule()
|
||||
{
|
||||
var steamVRTrackingModuleType = typeof(SteamVRTrackingModule);
|
||||
var constructor = steamVRTrackingModuleType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
|
||||
var instance = constructor.Invoke(null);
|
||||
return (SteamVRTrackingModule)instance;
|
||||
}
|
||||
}
|
48
DesktopVRSwitch/Patches/MovementSystemTracker.cs
Normal file
48
DesktopVRSwitch/Patches/MovementSystemTracker.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
using ABI_RC.Systems.MovementSystem;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.Melons.DesktopVRSwitch.Patches;
|
||||
|
||||
public class MovementSystemTracker : MonoBehaviour
|
||||
{
|
||||
public MovementSystem movementSystem;
|
||||
public Vector3 preSwitchWorldPosition;
|
||||
public Quaternion preSwitchWorldRotation;
|
||||
|
||||
void Start()
|
||||
{
|
||||
movementSystem = GetComponent<MovementSystem>();
|
||||
VRModeSwitchTracker.OnPostVRModeSwitch += PreVRModeSwitch;
|
||||
VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
VRModeSwitchTracker.OnPostVRModeSwitch -= PreVRModeSwitch;
|
||||
VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
|
||||
}
|
||||
|
||||
public void PreVRModeSwitch(bool isVR, 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).
|
||||
}
|
||||
|
||||
public void PostVRModeSwitch(bool isVR, 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 (!isVR) movementSystem.UpdateColliderCenter(movementSystem.transform.position);
|
||||
}
|
||||
}
|
91
DesktopVRSwitch/Patches/ReferenceCameraPatch.cs
Normal file
91
DesktopVRSwitch/Patches/ReferenceCameraPatch.cs
Normal file
|
@ -0,0 +1,91 @@
|
|||
using ABI_RC.Core.Base;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using Aura2API;
|
||||
using BeautifyEffect;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AzureSky;
|
||||
using UnityEngine.Rendering.PostProcessing;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace NAK.Melons.DesktopVRSwitch.Patches;
|
||||
|
||||
internal class ReferenceCameraPatch
|
||||
{
|
||||
internal static void OnWorldLoad()
|
||||
{
|
||||
Camera activeCamera = (MetaPort.Instance.isUsingVr ? PlayerSetup.Instance.vrCamera : PlayerSetup.Instance.desktopCamera).GetComponent<Camera>();
|
||||
Camera inactiveCamera = (MetaPort.Instance.isUsingVr ? PlayerSetup.Instance.desktopCamera : PlayerSetup.Instance.vrCamera).GetComponent<Camera>();
|
||||
CopyToInactiveCam(activeCamera, inactiveCamera);
|
||||
}
|
||||
|
||||
internal static void CopyToInactiveCam(Camera activeCam, Camera inactiveCam)
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg("Copying active camera settings & components to inactive camera.");
|
||||
|
||||
//steal basic settings
|
||||
inactiveCam.farClipPlane = activeCam.farClipPlane;
|
||||
inactiveCam.nearClipPlane = activeCam.nearClipPlane;
|
||||
inactiveCam.cullingMask = activeCam.cullingMask;
|
||||
inactiveCam.depthTextureMode = activeCam.depthTextureMode;
|
||||
|
||||
//steal post processing if added
|
||||
PostProcessLayer ppLayerActiveCam = activeCam.GetComponent<PostProcessLayer>();
|
||||
PostProcessLayer ppLayerInactiveCam = inactiveCam.AddComponentIfMissing<PostProcessLayer>();
|
||||
if (ppLayerActiveCam != null && ppLayerInactiveCam != null)
|
||||
{
|
||||
ppLayerInactiveCam.enabled = ppLayerActiveCam.enabled;
|
||||
ppLayerInactiveCam.volumeLayer = ppLayerActiveCam.volumeLayer;
|
||||
}
|
||||
|
||||
//what even is this aura camera stuff
|
||||
AuraCamera auraActiveCam = activeCam.GetComponent<AuraCamera>();
|
||||
AuraCamera auraInactiveCam = inactiveCam.AddComponentIfMissing<AuraCamera>();
|
||||
if (auraActiveCam != null && auraInactiveCam != null)
|
||||
{
|
||||
auraInactiveCam.enabled = auraActiveCam.enabled;
|
||||
auraInactiveCam.frustumSettings = auraActiveCam.frustumSettings;
|
||||
}
|
||||
else
|
||||
{
|
||||
auraInactiveCam.enabled = false;
|
||||
}
|
||||
|
||||
//flare layer thing? the sun :_:_:_:_:_:
|
||||
FlareLayer flareActiveCam = activeCam.GetComponent<FlareLayer>();
|
||||
FlareLayer flareInactiveCam = inactiveCam.AddComponentIfMissing<FlareLayer>();
|
||||
if (flareActiveCam != null && flareInactiveCam != null)
|
||||
{
|
||||
flareInactiveCam.enabled = flareActiveCam.enabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
flareInactiveCam.enabled = false;
|
||||
}
|
||||
|
||||
//and now what the fuck is fog scattering
|
||||
AzureFogScattering azureFogActiveCam = activeCam.GetComponent<AzureFogScattering>();
|
||||
AzureFogScattering azureFogInactiveCam = inactiveCam.AddComponentIfMissing<AzureFogScattering>();
|
||||
if (azureFogActiveCam != null && azureFogInactiveCam != null)
|
||||
{
|
||||
azureFogInactiveCam.fogScatteringMaterial = azureFogActiveCam.fogScatteringMaterial;
|
||||
}
|
||||
else
|
||||
{
|
||||
Object.Destroy(inactiveCam.GetComponent<AzureFogScattering>());
|
||||
}
|
||||
|
||||
//why is there so many thingsssssssss
|
||||
Beautify beautifyActiveCam = activeCam.GetComponent<Beautify>();
|
||||
Beautify beautifyInactiveCam = inactiveCam.AddComponentIfMissing<Beautify>();
|
||||
if (beautifyActiveCam != null && beautifyInactiveCam != null)
|
||||
{
|
||||
beautifyInactiveCam.quality = beautifyActiveCam.quality;
|
||||
beautifyInactiveCam.profile = beautifyActiveCam.profile;
|
||||
}
|
||||
else
|
||||
{
|
||||
Object.Destroy(inactiveCam.gameObject.GetComponent<Beautify>());
|
||||
}
|
||||
}
|
||||
}
|
45
DesktopVRSwitch/Patches/VRModeSwitchTracker.cs
Normal file
45
DesktopVRSwitch/Patches/VRModeSwitchTracker.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace NAK.Melons.DesktopVRSwitch.Patches;
|
||||
|
||||
public class VRModeSwitchTracker
|
||||
{
|
||||
public static event UnityAction<bool, Camera> OnPreVRModeSwitch;
|
||||
public static event UnityAction<bool, Camera> OnPostVRModeSwitch;
|
||||
public static event UnityAction<bool, Camera> OnFailVRModeSwitch;
|
||||
|
||||
public static void PreVRModeSwitch(bool isVR)
|
||||
{
|
||||
TryCatchHell.TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg("Invoking VRModeSwitchTracker.OnPreVRModeSwitch.");
|
||||
Camera activeCamera = PlayerSetup.Instance.GetActiveCamera().GetComponent<Camera>();
|
||||
VRModeSwitchTracker.OnPreVRModeSwitch?.Invoke(isVR, activeCamera);
|
||||
},
|
||||
"Error while invoking VRModeSwitchTracker.OnPreVRModeSwitch. Did someone do a fucky?");
|
||||
}
|
||||
|
||||
public static void PostVRModeSwitch(bool isVR)
|
||||
{
|
||||
TryCatchHell.TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg("Invoking VRModeSwitchTracker.OnPostVRModeSwitch.");
|
||||
Camera activeCamera = PlayerSetup.Instance.GetActiveCamera().GetComponent<Camera>();
|
||||
VRModeSwitchTracker.OnPostVRModeSwitch?.Invoke(isVR, activeCamera);
|
||||
},
|
||||
"Error while invoking VRModeSwitchTracker.OnPostVRModeSwitch. Did someone do a fucky?");
|
||||
}
|
||||
|
||||
public static void FailVRModeSwitch(bool isVR)
|
||||
{
|
||||
TryCatchHell.TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg("Invoking VRModeSwitchTracker.OnFailVRModeSwitch.");
|
||||
Camera activeCamera = PlayerSetup.Instance.GetActiveCamera().GetComponent<Camera>();
|
||||
VRModeSwitchTracker.OnFailVRModeSwitch?.Invoke(isVR, activeCamera);
|
||||
},
|
||||
"Error while invoking OnFailVRModeSwitch.OnPreVRModeSwitch. Did someone do a fucky?");
|
||||
}
|
||||
}
|
35
DesktopVRSwitch/Patches/VRTrackerManagerTracker.cs
Normal file
35
DesktopVRSwitch/Patches/VRTrackerManagerTracker.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.Melons.DesktopVRSwitch.Patches;
|
||||
|
||||
public class VRTrackerManagerTracker : MonoBehaviour
|
||||
{
|
||||
public VRTrackerManager vrTrackerManager;
|
||||
public Traverse _hasCheckedForKnucklesTraverse;
|
||||
public Traverse _posesTraverse;
|
||||
|
||||
void Start()
|
||||
{
|
||||
vrTrackerManager = GetComponent<VRTrackerManager>();
|
||||
_posesTraverse = Traverse.Create(vrTrackerManager).Field("poses");
|
||||
_hasCheckedForKnucklesTraverse = Traverse.Create(vrTrackerManager).Field("hasCheckedForKnuckles");
|
||||
VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
|
||||
}
|
||||
|
||||
public void PostVRModeSwitch(bool isVR, 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.leftHand = null;
|
||||
vrTrackerManager.rightHand = null;
|
||||
_posesTraverse.SetValue(null);
|
||||
_hasCheckedForKnucklesTraverse.SetValue(false);
|
||||
}
|
||||
}
|
31
DesktopVRSwitch/Properties/AssemblyInfo.cs
Normal file
31
DesktopVRSwitch/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using MelonLoader;
|
||||
using NAK.Melons.DesktopVRSwitch.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.Melons.DesktopVRSwitch))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.Melons.DesktopVRSwitch))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.Melons.DesktopVRSwitch.DesktopVRSwitchMod),
|
||||
nameof(NAK.Melons.DesktopVRSwitch),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidOnSteam/DesktopVRSwitch"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonColor(ConsoleColor.DarkCyan)]
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.Melons.DesktopVRSwitch.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "4.3.5";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
189
DesktopVRSwitch/TryCatchHell.cs
Normal file
189
DesktopVRSwitch/TryCatchHell.cs
Normal file
|
@ -0,0 +1,189 @@
|
|||
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 HarmonyLib;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.Melons.DesktopVRSwitch;
|
||||
|
||||
internal class TryCatchHell
|
||||
{
|
||||
internal static void TryCatchWrapper(Action action, string errorMsg, params object[] msgArgs)
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Error(string.Format(errorMsg, msgArgs));
|
||||
DesktopVRSwitchMod.Logger.Msg(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void CloseCohtmlMenus()
|
||||
{
|
||||
TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.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 isVR)
|
||||
{
|
||||
TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg($"Setting CheckVR hasVrDeviceLoaded to {isVR}.");
|
||||
CheckVR.Instance.hasVrDeviceLoaded = isVR;
|
||||
},
|
||||
"Setting CheckVR hasVrDeviceLoaded failed.");
|
||||
}
|
||||
|
||||
internal static void SetMetaPort(bool isVR)
|
||||
{
|
||||
TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg($"Setting MetaPort isUsingVr to {isVR}.");
|
||||
MetaPort.Instance.isUsingVr = isVR;
|
||||
},
|
||||
"Setting MetaPort isUsingVr failed.");
|
||||
}
|
||||
|
||||
internal static void RepositionCohtmlHud(bool isVR)
|
||||
{
|
||||
TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg("Configuring new hud affinity for CohtmlHud.");
|
||||
CohtmlHud.Instance.gameObject.transform.parent = isVR ? 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 isVR)
|
||||
{
|
||||
TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg("Switching HudOperations worldLoadingItem & worldLoadStatus.");
|
||||
HudOperations.Instance.worldLoadingItem = isVR ? HudOperations.Instance.worldLoadingItemVr : HudOperations.Instance.worldLoadingItemDesktop;
|
||||
HudOperations.Instance.worldLoadStatus = isVR ? HudOperations.Instance.worldLoadStatusVr : HudOperations.Instance.worldLoadStatusDesktop;
|
||||
},
|
||||
"Failed switching HudOperations objects.");
|
||||
}
|
||||
|
||||
internal static void DisableMirrorCanvas()
|
||||
{
|
||||
TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.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 isVR)
|
||||
{
|
||||
TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg("Switching active PlayerSetup camera rigs. Updating Desktop camera FOV.");
|
||||
PlayerSetup.Instance.desktopCameraRig.SetActive(!isVR);
|
||||
PlayerSetup.Instance.vrCameraRig.SetActive(isVR);
|
||||
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)
|
||||
{
|
||||
TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.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()
|
||||
{
|
||||
TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.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(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.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))
|
||||
{
|
||||
DesktopVRSwitchMod.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))
|
||||
{
|
||||
DesktopVRSwitchMod.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(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg("Updating CVRGestureRecognizer _camera to active camera.");
|
||||
Traverse.Create(CVRGestureRecognizer.Instance).Field("_camera").SetValue(PlayerSetup.Instance.GetActiveCamera().GetComponent<Camera>());
|
||||
},
|
||||
"Failed to update CVRGestureRecognizer camera.");
|
||||
}
|
||||
|
||||
internal static void UpdateMenuCoreData(bool isVR)
|
||||
{
|
||||
TryCatchWrapper(() =>
|
||||
{
|
||||
DesktopVRSwitchMod.Logger.Msg("Updating CVR_Menu_Data core data.");
|
||||
CVR_MenuManager.Instance.coreData.core.inVr = isVR;
|
||||
},
|
||||
"Failed to update CVR_Menu_Data core data.");
|
||||
}
|
||||
}
|
23
DesktopVRSwitch/format.json
Normal file
23
DesktopVRSwitch/format.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": 103,
|
||||
"name": "DesktopVRSwitch",
|
||||
"modversion": "4.3.5",
|
||||
"gameversion": "2022r170",
|
||||
"loaderversion": "0.5.7",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Allows you to switch between Desktop and VR with a keybind.\n**Press Control + F6 to switch.**\n\nWhile this mod is a nice convienence feature to have access to, not every chillout system or mod is built to support it. I cannot possibly cover every edge case or mitigate issues with every mod. **Use at your own discretion.**",
|
||||
"searchtags": [
|
||||
"desktop",
|
||||
"vr",
|
||||
"switch",
|
||||
"hotswap"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidOnSteam/DesktopVRSwitch/releases/download/v4.3.5/DesktopVRSwitch.dll",
|
||||
"sourcelink": "https://github.com/NotAKidOnSteam/DesktopVRSwitch/",
|
||||
"changelog": "- Reinitialize SteamVR input on switch. Correct fixedDeltaTime when entering Desktop.\n- Tweak to initial switch position for correcting offsets.\n- Fixed FBT tracking point initial size.\n- Update core menu data so QM Recalibrate/SeatedPlay button works.",
|
||||
"embedcolor": "3498db"
|
||||
}
|
62
README.md
62
README.md
|
@ -13,23 +13,8 @@ AAS will also not be updated unless the expected data matches what is received.
|
|||
The avatar will stay in the default animator state until AAS data is received that is deemed correct.
|
||||
|
||||
You will no longer sync garbage AAS while switching avatar.
|
||||
|
||||
# CVRGizmos
|
||||
Adds in-game gizmos to CCK components.
|
||||
|
||||
Current implementation may be a bit ugly, but at least it doesn't tank FPS.
|
||||
|
||||
Uses modified version of Popcron.Gizmos:
|
||||
|
||||
https://github.com/popcron/gizmos
|
||||
|
||||

|
||||
# ClearHudNotifications
|
||||
|
||||
Simple mod to clear hud notifications when joining an online instance. Can also manually clear notifications by pressing F4.
|
||||
|
||||
There is no native method to clear notifications, so I force an immediate notification to clear the buffer.
|
||||
|
||||
---
|
||||
# Blackout
|
||||
|
||||
Functionality heavily inspired by VRSleeper on Booth: https://booth.pm/ja/items/2151940
|
||||
|
@ -64,7 +49,27 @@ There is no native method to clear notifications, so I force an immediate notifi
|
|||
* Awake Threshold - Degrees of movement to return full vision.
|
||||
* Enter Drowsy Time - How many minutes without movement until enter drowsy mode.
|
||||
* Enter Sleep Time - How many seconds without movement until enter sleep mode.
|
||||
|
||||
|
||||
---
|
||||
# ClearHudNotifications
|
||||
|
||||
Simple mod to clear hud notifications when joining an online instance. Can also manually clear notifications by pressing F4.
|
||||
|
||||
There is no native method to clear notifications, so I force an immediate notification to clear the buffer.
|
||||
|
||||
---
|
||||
# CVRGizmos
|
||||
Adds in-game gizmos to CCK components.
|
||||
|
||||
Current implementation may be a bit ugly, but at least it doesn't tank FPS.
|
||||
|
||||
Uses modified version of Popcron.Gizmos:
|
||||
|
||||
https://github.com/popcron/gizmos
|
||||
|
||||

|
||||
|
||||
---
|
||||
# DesktopVRIK
|
||||
Adds VRIK to Desktop ChilloutVR avatars. No longer will you be a liveless sliding statue~!
|
||||
|
||||
|
@ -85,6 +90,27 @@ https://user-images.githubusercontent.com/37721153/221870123-fbe4f5e8-8d6e-4a43-
|
|||
https://feedback.abinteractive.net/p/desktop-feet-ik-for-avatars
|
||||
|
||||
https://feedback.abinteractive.net/p/pivot-desktop-camera-with-head
|
||||
|
||||
---
|
||||
# DesktopVRSwitch
|
||||
Allows you to switch between Desktop and VR with a keybind.
|
||||
|
||||
Press Control + F6 to switch. SteamVR will automatically start if it isn't already running.
|
||||
|
||||
---
|
||||
|
||||
Almost all base game features & systems that differ when in VR are now updated after switch. There are still very likely small quirks that need ironing out still, but everything major is now fixed and accounted for.
|
||||
|
||||
This mod will likely cause issues with other mods that are not built for or expect VRMode changes during runtime.
|
||||
|
||||
## There are two versions of this mod!
|
||||
**DesktopVRSwitch** is built for the Stable branch of ChilloutVR. (OpenVR)
|
||||
|
||||
**DesktopXRSwitch** is built for the Experimental branch of ChilloutVR (OpenXR)
|
||||
|
||||
Once the Experimental branch of ChilloutVR hits Stable, the mod name will be changing from VR -> XR.
|
||||
|
||||
---
|
||||
# FuckMetrics
|
||||
|
||||
This mod limits UpdateMetrics & SendCoreUpdate while the menus are closed. This helps to alleviate hitching and performance issues, particularly with FPS drops while unmuted in online instances and VRIK tapping in place.
|
||||
|
@ -255,7 +281,7 @@ https://user-images.githubusercontent.com/37721153/231351589-07f794f3-f542-4cb4-
|
|||
## Relevant Feedback Posts:
|
||||
https://feedback.abinteractive.net/p/z-for-undo-in-game
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue