From c092322db009834cd2bd2acb57f727da7b6446de Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:23:54 +0000 Subject: [PATCH 001/252] Fix build config --- BetterVR/BetterVR.csproj | 214 +++++++++++++++++++++------------------ 1 file changed, 116 insertions(+), 98 deletions(-) diff --git a/BetterVR/BetterVR.csproj b/BetterVR/BetterVR.csproj index 9c02d14..1fd64c9 100644 --- a/BetterVR/BetterVR.csproj +++ b/BetterVR/BetterVR.csproj @@ -1,144 +1,162 @@ - + Debug AnyCPU - {FAE04EC0-301F-11D3-BF4B-00C04F79EFBF} - library - netcoreapp3.1 + {930A00A6-2935-4EA0-81F0-B16D3E71B74F} + Library + Properties + net46 BetterVR HS2_BetterVR - v4.6 512 true + false + true true - embedded + pdbonly false ..\bin\HS2_BetterVR\BepInEx\plugins DEBUG;TRACE;HS2 prompt - 4 - false + 3 + CppCoreCheckRules.ruleset + x64 - embedded + pdbonly true ..\bin\HS2_BetterVR\BepInEx\plugins TRACE;HS2 prompt - 4 - true - false + 3 + x64 - - - False - ..\packages\IllusionLibs.BepInEx.Harmony.2.2.0.1\lib\net35\0Harmony.dll - False - - - ..\packages\IllusionLibs.HoneySelect2.Assembly-CSharp.2020.5.29.2\lib\net46\Assembly-CSharp_VR.dll - False - - - ..\packages\IllusionLibs.HoneySelect2.Assembly-CSharp-firstpass.2020.5.29.2\lib\net46\Assembly-CSharp-firstpass.dll - False - - - ..\packages\IllusionLibs.BepInEx.5.1.0\lib\net35\BepInEx.dll - False - False - - - ..\packages\IllusionLibs.BepInEx.Harmony.2.0.3.1\lib\net35\BepInEx.Harmony.dll - False - - - ..\packages\ABMX.HS2ABMX.4.4.1\lib\net46\HS2ABMX.dll - False - False - - - ..\packages\IllusionModdingAPI.HS2API.1.15.0\lib\net46\HS2API.dll - False - False - - - ..\packages\ExtensibleSaveFormat.HoneySelect2.16.2.0.2\lib\net46\HS2_ExtensibleSaveFormat.dll - False - False - - - ..\packages\IllusionLibs.HoneySelect2.Sirenix.Serialization.2020.5.29.2\lib\net46\Sirenix.Serialization.dll + + + ..\packages\IllusionLibs.BepInEx.Harmony.2.9.0\lib\net35\0Harmony.dll + False + + + ..\packages\IllusionLibs.HoneySelect2.Assembly-CSharp.2020.5.29.4\lib\net46\Assembly-CSharp.dll + False + + + ..\packages\IllusionLibs.HoneySelect2.Assembly-CSharp-firstpass.2020.5.29.4\lib\net46\Assembly-CSharp-firstpass.dll + True + True + + + ..\packages\IllusionLibs.BepInEx.5.4.22\lib\net35\BepInEx.dll + True + True + + + ..\packages\IllusionLibs.BepInEx.5.4.22\lib\net35\BepInEx.dll + False + + + ..\packages\ABMX.HS2ABMX.5.0.6\lib\net46\HS2ABMX.dll + True + True + + + ..\packages\IllusionModdingAPI.HS2API.1.36.0\lib\net46\HS2API.dll + True + True + + + ..\packages\IllusionModdingAPI.HS2API.1.36.0\lib\net46\HS2API.dll False False - - ..\packages\IllusionLibs.HoneySelect2.UnityEngine.CoreModule.2018.4.11.2\lib\net46\UnityEngine.dll - False - - - ..\packages\IllusionLibs.HoneySelect2.UniRx.2020.5.29.2\lib\net46\UniRx.dll - False - - - ..\packages\IllusionLibs.HoneySelect2.UnityEngine.CoreModule.2018.4.11.2\lib\net46\UnityEngine.CoreModule.dll - False - - - ..\packages\IllusionLibs.HoneySelect2.UnityEngine.PhysicsModule.2018.4.11.2\lib\net46\UnityEngine.PhysicsModule.dll - False - - - ..\packages\IllusionLibs.HoneySelect2.UnityEngine.UI.2018.4.11.2\lib\net46\UnityEngine.UI.dll - False - - - ..\packages\IllusionLibs.HoneySelect2.UnityEngine.IMGUIModule.2018.4.11.2\lib\net46\UnityEngine.IMGUIModule.dll - False - - - ..\packages\IllusionLibs.HoneySelect2.UnityEngine.TextRenderingModule.2018.4.11.2\lib\net46\UnityEngine.TextRenderingModule.dll - False - - - ..\packages\IllusionLibs.HoneySelect2.IL.2020.5.29.2\lib\net46\IL.dll - False + + ..\packages\ExtensibleSaveFormat.HoneySelect2.19.3.0\lib\net46\HS2_ExtensibleSaveFormat.dll + True + True + + + ..\packages\IllusionLibs.HoneySelect2.IL.2020.5.29.4\lib\net46\IL.dll + True + True + + + ..\packages\IllusionLibs.HoneySelect2.Sirenix.Serialization.2020.5.29.4\lib\net46\Sirenix.Serialization.dll + True + True + + + ..\packages\IllusionLibs.HoneySelect2.UniRx.2020.5.29.4\lib\net46\UniRx.dll + True + True + + + ..\packages\IllusionLibs.HoneySelect2.Unity.TextMeshPro.2018.4.11.4\lib\net46\Unity.TextMeshPro.dll + True + True + + + ..\packages\IllusionLibs.HoneySelect2.UnityEngine.CoreModule.2018.4.11.4\lib\net46\UnityEngine.dll + True + True + + + ..\packages\IllusionLibs.HoneySelect2.UnityEngine.CoreModule.2018.4.11.4\lib\net46\UnityEngine.CoreModule.dll + True + True + + + ..\packages\IllusionLibs.HoneySelect2.UnityEngine.ImageConversionModule.2018.4.11.4\lib\net46\UnityEngine.ImageConversionModule.dll + True + True + + + ..\packages\IllusionLibs.HoneySelect2.UnityEngine.IMGUIModule.2018.4.11.4\lib\net46\UnityEngine.IMGUIModule.dll + True + True + + + ..\packages\IllusionLibs.HoneySelect2.UnityEngine.PhysicsModule.2018.4.11.4\lib\net46\UnityEngine.PhysicsModule.dll + True + True + + + ..\packages\IllusionLibs.HoneySelect2.UnityEngine.TextRenderingModule.2018.4.11.4\lib\net46\UnityEngine.TextRenderingModule.dll + True + True ..\packages\SteamVR.dll False + + + ..\packages\IllusionLibs.HoneySelect2.UnityEngine.UI.2018.4.11.4\lib\net46\UnityEngine.UI.dll + True + True + + + + ..\packages\IllusionLibs.HoneySelect2.UnityEngine.UIModule.2018.4.11.4\lib\net46\UnityEngine.UIModule.dll + True + True + - - - - - - - - - - - + - - - - From c46786ef209204646740f2bc7fd0f82b401fae42 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:25:17 +0000 Subject: [PATCH 002/252] Two handed rotation --- BetterVR/BetterVRPlugin.cs | 45 ++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index e75cf5d..9f7ee53 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -1,5 +1,7 @@ using BepInEx; using BepInEx.Logging; +using Manager; +using HTC.UnityPlugin.Vive; using HarmonyLib; namespace BetterVR @@ -23,19 +25,17 @@ public partial class BetterVRPlugin : BaseUnityPlugin internal void Start() { Logger = base.Logger; - DebugTools.logger = Logger; + // DebugTools.logger = Logger; VRControllerColliderHelper.pluginInstance = this; PluginConfigInit(); //Set up game mode detectors to start certain logic when loading into main game VRControllerColliderHelper.TriggerHelperCoroutine(); - //Watch for headset initialized - BetterVRPluginHelper.CheckForVROrigin(this); //Harmony init. It's magic! - // Harmony harmony_controller = new Harmony(GUID + "_controller"); - // VRControllerHooks.InitHooks(harmony_controller, this); + Harmony harmony_controller = new Harmony(GUID + "_controller"); + VRControllerHooks.InitHooks(harmony_controller, this); Harmony harmony_menu = new Harmony(GUID + "_menu"); VRMenuHooks.InitHooks(harmony_menu, this); @@ -56,14 +56,45 @@ internal void Start() internal void Update() { // if (BetterVRPlugin.debugLog && Time.frameCount % 10 == 0) BetterVRPlugin.Logger.LogInfo($" SqueezeToTurn {SqueezeToTurn.Value} VRControllerInput.VROrigin {VRControllerInput.VROrigin}"); - if (BetterVRPluginHelper.VROrigin == null) BetterVRPluginHelper.CheckForVROrigin(this); //When the user squeezes the controller, apply hand rotation to headset if (SqueezeToTurn.Value && BetterVRPluginHelper.VROrigin != null) { VRControllerInput.CheckInputForSqueezeTurn(); } + + if (ViveInput.GetPressUpEx(HandRole.LeftHand, ControllerButton.AKey)) { + if (ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Trigger)) + { + BetterVRPluginHelper.ResetView(); + } + else + { + // Toggle player part visibility. + Manager.Config.HData.Son = !Manager.Config.HData.Son; + } + } + + if (!ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Trigger) && + ViveInput.GetPressUpEx(HandRole.RightHand, ControllerButton.AKey)) + { + // Toggle player body visibility. + Manager.Config.HData.Visible = !Manager.Config.HData.Visible; + } + + HideMonochromeP(); } + private static void HideMonochromeP() + { + HScene hScene = Singleton.Instance.Hscene; + if (hScene == null) return; + var chaControl = hScene.GetMales()[0]; + if (chaControl == null) return; + chaControl.cmpSimpleBody.targetEtc.objDanTop?.SetActive(false); + chaControl.cmpSimpleBody.targetEtc.objMNPB?.SetActive(false); + chaControl.cmpSimpleBody.targetEtc.objDanSao?.SetActive(false); + chaControl.cmpSimpleBody.targetEtc.objDanTama?.SetActive(false); + } } -} \ No newline at end of file +} From b12e98cd71b2a61a0446eaac934b7d7f2bff5a22 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:26:00 +0000 Subject: [PATCH 003/252] View reset and privacy screen --- BetterVR/BetterVRPlugin.Helper.cs | 98 +++++++++++++++---------------- 1 file changed, 47 insertions(+), 51 deletions(-) diff --git a/BetterVR/BetterVRPlugin.Helper.cs b/BetterVR/BetterVRPlugin.Helper.cs index 04f4087..6dcaea4 100644 --- a/BetterVR/BetterVRPlugin.Helper.cs +++ b/BetterVR/BetterVRPlugin.Helper.cs @@ -1,14 +1,14 @@ using UnityEngine; -using System.Collections; +using UnityEngine.UI; +using UnityEngine.Events; +using HS2VR; namespace BetterVR { public static class BetterVRPluginHelper { public static GameObject VROrigin; - public static bool init = true;//False once headset GameObject found - internal static bool isRunning = false;//True while actively searching for headset GameObject - + public static UnityEvent recenterVR { set; private get; } public enum VR_Hand { @@ -17,33 +17,9 @@ public enum VR_Hand none } - - /// - /// Get the top level VR game object - /// - internal static GameObject GetVROrigin() - { - if (VROrigin == null) - { - VROrigin = GameObject.Find("VROrigin"); - - //Show vr controler GO tree - if (VROrigin != null && init) { - init = false; - if (BetterVRPlugin.debugLog) DebugTools.LogChildrenComponents(VROrigin, true); - } - } - - // var origin = SteamVR_Render.Top()?.origin; //The headset rig render - // if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" SteamVR Origin {origin?.gameObject}"); - - return VROrigin; - } - - - /// + /// Use an enum to get the correct hand - /// + /// internal static GameObject GetHand(VR_Hand hand) { if (hand == VR_Hand.left) return GetLeftHand(); @@ -59,6 +35,7 @@ internal static GameObject GetHand(VR_Hand hand) internal static GameObject GetLeftHand() { var leftHand = GameObject.Find("ViveControllers/Left"); + if (leftHand == null) leftHand = GameObject.Find("Controller (left)"); if (leftHand == null) return null; if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" GetLeftHand id {leftHand.GetInstanceID()}"); @@ -70,6 +47,7 @@ internal static GameObject GetLeftHand() internal static GameObject GetRightHand() { var rightHand = GameObject.Find("ViveControllers/Right"); + if (rightHand == null) rightHand = GameObject.Find("Controller (right)"); if (rightHand == null) return null; if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" GetRightHand id {rightHand.GetInstanceID()}"); @@ -77,30 +55,14 @@ internal static GameObject GetRightHand() return rightHand.gameObject; } - - internal static void CheckForVROrigin(BetterVRPlugin instance) - { - if (BetterVRPluginHelper.isRunning) return; - instance.StartCoroutine(BetterVRPluginHelper.Init()); - } - - /// /// Lazy wait for VR headset origin to exists /// - internal static IEnumerator Init() + internal static void Init(GameObject VROrigin) { - isRunning = true; - - while (BetterVRPluginHelper.VROrigin == null) - { - BetterVRPluginHelper.GetVROrigin(); - yield return new WaitForSeconds(1); - } - + BetterVRPluginHelper.VROrigin = VROrigin; BetterVRPluginHelper.FixWorldScale(); - - isRunning = false; + BetterVRPluginHelper.UpdatePrivacyScreen(); } @@ -112,9 +74,43 @@ public static void FixWorldScale(bool enable = true) var viveRig = GameObject.Find("ViveRig"); if (viveRig != null) { - viveRig.transform.localScale = Vector3.one * (enable ? 1.10f : 1); + viveRig.transform.localScale = Vector3.one * (enable ? BetterVRPlugin.PlayerScale.Value : 1); + + } + } + + // Moves VR camera to the player's head. + internal static void ResetView() + { + recenterVR?.Invoke(); + VRSettingUI.CameraInitAction?.Invoke(); + } + + private static GameObject privacyScreen; + public static void UpdatePrivacyScreen() + { + EnsurePrivacyScreen().SetActive(BetterVRPlugin.UsePrivacyScreen.Value); + } + + private static GameObject EnsurePrivacyScreen() { + if (privacyScreen != null) + { + return privacyScreen; } + + privacyScreen = new GameObject("PrivacyMode"); + Canvas privacyCanvas = privacyScreen.AddComponent(); + privacyCanvas.renderMode = RenderMode.ScreenSpaceOverlay; + privacyCanvas.sortingOrder = 30000; + GameObject privacyOverlay = new GameObject("Overlay"); + privacyOverlay.transform.SetParent(privacyScreen.transform); + Image image = privacyOverlay.AddComponent(); + image.rectTransform.sizeDelta = new Vector2((float)(Screen.width * 4), (float)(Screen.height * 4)); + image.color = Color.black; + UnityEngine.Object.DontDestroyOnLoad(privacyScreen); + + return privacyScreen; } } -} \ No newline at end of file +} From e35be52ee5198995830cacd83e97dc31b8d73390 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:26:24 +0000 Subject: [PATCH 004/252] Fix build config --- BetterVR/packages.config | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/BetterVR/packages.config b/BetterVR/packages.config index 0a60405..b463c4a 100644 --- a/BetterVR/packages.config +++ b/BetterVR/packages.config @@ -1,21 +1,21 @@ - + - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + From d0914d6495cfaa178ad0e61dbc890998c22fe9a7 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:26:50 +0000 Subject: [PATCH 005/252] Update VRController.Collider.cs --- BetterVR/VRController.Collider.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/BetterVR/VRController.Collider.cs b/BetterVR/VRController.Collider.cs index ff8bdbe..5b12ab5 100644 --- a/BetterVR/VRController.Collider.cs +++ b/BetterVR/VRController.Collider.cs @@ -17,8 +17,7 @@ internal static void SetVRControllerColliderToDynamicBones() if (dynamicBonesV2.Length == 0 && dynamicBones.Length == 0) return; //Get the top level VR game object - var VROrigin = BetterVRPluginHelper.GetVROrigin(); - if (VROrigin == null) return; + if (BetterVRPluginHelper.VROrigin == null) return; //Get the controller objects we want to attach colliders to.transform.gameObject var leftHand = BetterVRPluginHelper.GetLeftHand(); @@ -83,7 +82,7 @@ internal static DynamicBoneCollider GetOrAttachCollider(GameObject controllerGam /// /// Adds a dynamic bone collider to a controller GO (Thanks Anon11) /// - internal static DynamicBoneCollider AddDBCollider(GameObject controllerGameObject, string colliderName, float colliderRadius = 0.1f, float collierHeight = 0f, + internal static DynamicBoneCollider AddDBCollider(GameObject controllerGameObject, string colliderName, float colliderRadius = 0.05f, float collierHeight = 0f, Vector3 colliderCenter = new Vector3(), DynamicBoneCollider.Direction colliderDirection = default) { var renderModelTf = GetColliderPosition(controllerGameObject); @@ -97,13 +96,13 @@ internal static DynamicBoneCollider AddDBCollider(GameObject controllerGameObjec collider.m_Center = colliderCenter; collider.m_Direction = colliderDirection; colliderObject.transform.SetParent(renderModelTf, false); - + //Move the collider more into the hand for the index controller // var localPos = renderModelTf.up * -0.09f + renderModelTf.forward * -0.075f; // var localPos = renderModelTf.forward * -0.075f; // colliderObject.transform.localPosition = localPos; - if (BetterVRPlugin.debugLog) DebugTools.DrawSphereAndAttach(renderModelTf, colliderRadius); + // if (BetterVRPlugin.debugLog) DebugTools.DrawSphereAndAttach(renderModelTf, colliderRadius); // if (BetterVRPlugin.debugLog) DebugTools.DrawLineAndAttach(renderModelTf, renderModelTf.TransformPoint(localPos), renderModelTf.position, localPos); return collider; @@ -159,4 +158,4 @@ internal static void AddControllerColliderToDB(DynamicBoneCollider controllerCol } } -} \ No newline at end of file +} From 861b5d3a11f2e2e9ed274839ffb0be27b6a28692 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:27:46 +0000 Subject: [PATCH 006/252] Fix thumbstick input --- BetterVR/VRController.Hooks.cs | 42 ++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/BetterVR/VRController.Hooks.cs b/BetterVR/VRController.Hooks.cs index 46c3e17..7de3302 100644 --- a/BetterVR/VRController.Hooks.cs +++ b/BetterVR/VRController.Hooks.cs @@ -1,4 +1,6 @@ +using HTC.UnityPlugin.Vive; using HarmonyLib; +using UnityEngine; namespace BetterVR { @@ -24,9 +26,11 @@ internal static void LaserPointer_SetLeftLaserPointerActive(ControllerManager __ //If the pointer game object is active, then set the cursor angle if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" LaserPointer L active, setting angle to {BetterVRPlugin.SetVRControllerPointerAngle.Value}"); - pluginInstance.StartCoroutine( - VRControllerPointer.SetAngleAfterTime(BetterVRPlugin.SetVRControllerPointerAngle.Value, BetterVRPluginHelper.VR_Hand.left) - ); + + // Not working currently. + // pluginInstance.StartCoroutine( + // VRControllerPointer.SetAngleAfterTime(BetterVRPlugin.SetVRControllerPointerAngle.Value, BetterVRPluginHelper.VR_Hand.left) + // ); } @@ -38,10 +42,34 @@ internal static void LaserPointer_SetRightLaserPointerActive(ControllerManager _ //If the pointer game object is active, then set the cursor angle if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" LaserPointer R active, setting angle to {BetterVRPlugin.SetVRControllerPointerAngle.Value}"); - pluginInstance.StartCoroutine( - VRControllerPointer.SetAngleAfterTime(BetterVRPlugin.SetVRControllerPointerAngle.Value, BetterVRPluginHelper.VR_Hand.right) - ); + + // Not working currently. + // pluginInstance.StartCoroutine( + // VRControllerPointer.SetAngleAfterTime(BetterVRPlugin.SetVRControllerPointerAngle.Value, BetterVRPluginHelper.VR_Hand.right) + // ); } + [HarmonyPrefix, HarmonyPatch(typeof(HScene), "GetAxis")] + public static bool PatchGetAxis(HScene __instance, HandRole _hand, ref Vector2 __result) + { + if (_hand != HandRole.RightHand) + { + // For safety, fall back to vanilla logic in left hand as a workaround in case there is something missing in this patch. + return true; + } + + // This method works for Oculus controllers' thumbsticks too. + var axis = ViveInput.GetPadAxisEx(HandRole.RightHand); + + if (axis == Vector2.zero) + { + return true; + } + + // The vanilla pad/thumb stick detection is half broken and does not work on some platforms, giving rise to the necessity of this patch. + __result = axis; + + return false; + } } -} \ No newline at end of file +} From c54f8329413200b29e2517777e3932f2c80c93d1 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:28:17 +0000 Subject: [PATCH 007/252] Two handed rotation --- BetterVR/VRController.Input.cs | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index 47c87ef..1076236 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -15,25 +15,20 @@ public static class VRControllerInput /// internal static void CheckInputForSqueezeTurn() { - //When squeezing the grip, apply hand rotation to the headset - if (ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip)) + //When squeezing both grips, apply hand rotation to the headset + if (ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip) && ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip)) { - BetterVRPluginHelper.GetVROrigin(); - if (BetterVRPluginHelper.VROrigin == null) return; + if (!BetterVRPluginHelper.VROrigin) + { + return; + } + var handVelocityDifference = VivePose.GetVelocity(roleR) - VivePose.GetVelocity(roleL); + var handPositionDifference = VivePose.GetPose(roleR).TransformPoint(Vector3.zero) - VivePose.GetPose(roleL).TransformPoint(Vector3.zero); + handVelocityDifference.y = 0; + handPositionDifference.y = 0; + var angularSpeed = Vector3.Cross(handPositionDifference, handVelocityDifference).y / handPositionDifference.sqrMagnitude; - //Hand velocity along Y axis - var velocity = VivePose.GetAngularVelocity(roleL); - BetterVRPluginHelper.VROrigin.transform.Rotate(0f, -(velocity.y * Time.deltaTime * 100)/3f, 0f, Space.Self); - } - - //Do for both hands - if (ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip)) - { - BetterVRPluginHelper.GetVROrigin(); - if (BetterVRPluginHelper.VROrigin == null) return; - - var velocity = VivePose.GetAngularVelocity(roleR); - BetterVRPluginHelper.VROrigin.transform.Rotate(0f, -(velocity.y * Time.deltaTime * 100)/3f, 0f, Space.Self); + BetterVRPluginHelper.VROrigin.transform.Rotate(0f, -(angularSpeed * Time.deltaTime * 100)/3f, 0f, Space.Self); } //Oculus input @@ -44,4 +39,4 @@ internal static void CheckInputForSqueezeTurn() // return OVRInput.Get(OVRInput.RawAxis2D.RThumbstick, OVRInput.Controller.Active); } } -} \ No newline at end of file +} From 28b7fe1b04cd3adbf435ee0b99e1081abed1d43e Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:29:03 +0000 Subject: [PATCH 008/252] Use the same VROrigin that the vanilla game uses for locomotion --- BetterVR/VRMenu.Hooks.cs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/BetterVR/VRMenu.Hooks.cs b/BetterVR/VRMenu.Hooks.cs index 7d6bac8..983767f 100644 --- a/BetterVR/VRMenu.Hooks.cs +++ b/BetterVR/VRMenu.Hooks.cs @@ -1,6 +1,9 @@ using HarmonyLib; using HS2VR; using Manager; +using System.Reflection; +using UnityEngine; +using UnityEngine.UI; namespace BetterVR { @@ -34,6 +37,24 @@ internal static void VRSelectScene_Start(VRSelectScene __instance) VRMenuRandom.VRSelectSceneStart(); } + [HarmonyPostfix, HarmonyPatch(typeof(GripMoveCrtl), "Start")] + internal static void FindVrOrigin(GripMoveCrtl __instance) + { + GameObject objVROrigin = (GameObject) typeof(GripMoveCrtl).GetField("objVROrigin", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + if (objVROrigin) + { + BetterVRPluginHelper.Init(objVROrigin); + } + } + [HarmonyPostfix, HarmonyPatch(typeof(VRSettingUI), "Start")] + internal static void FindResetViewButton(VRSettingUI __instance) + { + Button recenterButton = (Button) typeof(VRSettingUI).GetField("btnRecenter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + if (recenterButton != null) + { + BetterVRPluginHelper.recenterVR = recenterButton.onClick; + } + } } -} \ No newline at end of file +} From 0fbefd0db2baf67ab1cc4a4741abace1f0797e1d Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:29:34 +0000 Subject: [PATCH 009/252] Fix build config --- nuget.config | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nuget.config b/nuget.config index 07d96a7..f7d1ec1 100644 --- a/nuget.config +++ b/nuget.config @@ -5,6 +5,7 @@ - - - \ No newline at end of file + + + + From 0b785793efa419defd1251debd9983d7dd23828c Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 21 Nov 2023 04:32:38 +0000 Subject: [PATCH 010/252] Adjustable player scale --- BetterVR/GUI/BetterVRPlugin.Config.cs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/BetterVR/GUI/BetterVRPlugin.Config.cs b/BetterVR/GUI/BetterVRPlugin.Config.cs index d2c7098..3f0ad38 100644 --- a/BetterVR/GUI/BetterVRPlugin.Config.cs +++ b/BetterVR/GUI/BetterVRPlugin.Config.cs @@ -7,9 +7,12 @@ public partial class BetterVRPlugin { public static ConfigEntry EnableControllerColliders { get; private set; } public static ConfigEntry SetVRControllerPointerAngle { get; private set; } + + public static ConfigEntry PlayerScale { get; private set; } public static ConfigEntry SqueezeToTurn { get; private set; } public static ConfigEntry FixWorldSizeScale { get; private set; } public static ConfigEntry MultipleRandomHeroine { get; private set; } + public static ConfigEntry UsePrivacyScreen { get; private set; } /// @@ -25,6 +28,11 @@ public void PluginConfigInit() SqueezeToTurn = Config.Bind("VR General", "Squeeze to Turn", true, new ConfigDescription("Allows you to turn the headset with hand rotation while zqueezing the controller.")); + PlayerScale = Config.Bind("VR General", "Player Scale", 1.15f, + new ConfigDescription("Player scale when fixing world size scale, default is 1.15", + new AcceptableValueRange(0.5f, 2f))); + PlayerScale.SettingChanged += FixWorldSizeScale_SettingsChanged; + // SetVRControllerPointerAngle = Config.Bind("VR General", "(Not working yet)Laser Pointer Angle", 0, // new ConfigDescription("0 is the default angle, and negative is down.", // new AcceptableValueRange(-90, 90))); @@ -35,9 +43,12 @@ public void PluginConfigInit() FixWorldSizeScale.SettingChanged += FixWorldSizeScale_SettingsChanged; MultipleRandomHeroine = Config.Bind("VR General", "Multiple Heroine when Random", false, - new ConfigDescription("Will add 2 Heroine to the HScene when the 'Random' button is selected. (Default is 1)")); + new ConfigDescription("Will add 2 Heroine to the HScene when the 'Random' button is selected. (Default is 1)")); - } + UsePrivacyScreen = Config.Bind("VR General", "Use Privacy Screen", true, + new ConfigDescription("Puts a black screen on desktop window")); + UsePrivacyScreen.SettingChanged += UsePrivacyScreen_SettingsChanged; + } /// @@ -67,6 +78,9 @@ internal void FixWorldSizeScale_SettingsChanged(object sender, System.EventArgs BetterVRPluginHelper.FixWorldScale(FixWorldSizeScale.Value); } - + internal void UsePrivacyScreen_SettingsChanged(object sender, System.EventArgs e) + { + BetterVRPluginHelper.UpdatePrivacyScreen(); + } } -} \ No newline at end of file +} From ce745c35ecff9353970f9d0004d780169349b951 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 21 Dec 2023 01:27:41 +0000 Subject: [PATCH 011/252] Update BetterVRPlugin.Config.cs --- BetterVR/GUI/BetterVRPlugin.Config.cs | 49 ++++++++++++++++++--------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/BetterVR/GUI/BetterVRPlugin.Config.cs b/BetterVR/GUI/BetterVRPlugin.Config.cs index 3f0ad38..047579a 100644 --- a/BetterVR/GUI/BetterVRPlugin.Config.cs +++ b/BetterVR/GUI/BetterVRPlugin.Config.cs @@ -1,19 +1,25 @@ using BepInEx.Configuration; using HarmonyLib; +using UnityEngine; namespace BetterVR { - public partial class BetterVRPlugin + public partial class BetterVRPlugin { public static ConfigEntry EnableControllerColliders { get; private set; } + public static ConfigEntry GestureStrip { get; private set; } public static ConfigEntry SetVRControllerPointerAngle { get; private set; } - - public static ConfigEntry PlayerScale { get; private set; } - public static ConfigEntry SqueezeToTurn { get; private set; } + public static ConfigEntry PlayerLogScale { get; private set; } + public static ConfigEntry SqueezeToTurn { get; private set; } + public static ConfigEntry AllowVerticalRotation { get; private set; } public static ConfigEntry FixWorldSizeScale { get; private set; } public static ConfigEntry MultipleRandomHeroine { get; private set; } public static ConfigEntry UsePrivacyScreen { get; private set; } + public static float PlayerScale { + get { return Mathf.Pow(2, PlayerLogScale.Value); } + set { PlayerLogScale.Value = Mathf.Log(value, 2); } + } /// /// Init the Bepinex config manager options @@ -23,15 +29,29 @@ public void PluginConfigInit() EnableControllerColliders = Config.Bind("VR General", "Enable Controller Colliders (boop!)", true, "Allows collision of VR controllers with all dynamic bones"); - EnableControllerColliders.SettingChanged += EnableControllerColliders_SettingsChanged; - - SqueezeToTurn = Config.Bind("VR General", "Squeeze to Turn", true, - new ConfigDescription("Allows you to turn the headset with hand rotation while zqueezing the controller.")); - - PlayerScale = Config.Bind("VR General", "Player Scale", 1.15f, - new ConfigDescription("Player scale when fixing world size scale, default is 1.15", - new AcceptableValueRange(0.5f, 2f))); - PlayerScale.SettingChanged += FixWorldSizeScale_SettingsChanged; + EnableControllerColliders.SettingChanged += EnableControllerColliders_SettingsChanged; + + GestureStrip = Config.Bind( + "VR General", "Enable Gesture Strip", "Right hand", + new ConfigDescription( + "Enable holding trigger and dragging to change cloth states.", + new AcceptableValueList(new string[] { "Disabled", "Left hand", "Right hand" }))); + + SqueezeToTurn = Config.Bind( + "VR General", "Squeeze to Turn", "One-handed", + new ConfigDescription( + "Allows you to turn the headset with hand rotation while squeezing the controller.", + new AcceptableValueList(new string[] { "Disabled", "One-handed", "Two-handed"}))); + + AllowVerticalRotation = Config.Bind( + "VR General", "Allow Vertical Rotation", false, new ConfigDescription("Allows rotating the world vertically.")); + + PlayerLogScale = Config.Bind( + "VR General", "Log2 of Player Scale", Mathf.Log(1.15f, 2f), + new ConfigDescription( + "Log2 of player scale when fixing world size scale, default is Log2(1.15)", + new AcceptableValueRange(-4, 4))); + PlayerLogScale.SettingChanged += FixWorldSizeScale_SettingsChanged; // SetVRControllerPointerAngle = Config.Bind("VR General", "(Not working yet)Laser Pointer Angle", 0, // new ConfigDescription("0 is the default angle, and negative is down.", @@ -50,7 +70,6 @@ public void PluginConfigInit() UsePrivacyScreen.SettingChanged += UsePrivacyScreen_SettingsChanged; } - /// /// On config options changed by user, trigger stuff /// @@ -66,13 +85,11 @@ internal void EnableControllerColliders_SettingsChanged(object sender, System.Ev } } - // internal void SetVRControllerPointerAngle_SettingsChanged(object sender, System.EventArgs e) // { // VRControllerPointer.UpdateOneOrMoreCtrlPointers(SetVRControllerPointerAngle.Value); // } - internal void FixWorldSizeScale_SettingsChanged(object sender, System.EventArgs e) { BetterVRPluginHelper.FixWorldScale(FixWorldSizeScale.Value); From b8664d81646e1f97766e94bedc6b11da10a776c5 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 21 Dec 2023 01:29:32 +0000 Subject: [PATCH 012/252] Update BetterVRPlugin.Helper.cs --- BetterVR/BetterVRPlugin.Helper.cs | 60 +++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/BetterVR/BetterVRPlugin.Helper.cs b/BetterVR/BetterVRPlugin.Helper.cs index 6dcaea4..02c6193 100644 --- a/BetterVR/BetterVRPlugin.Helper.cs +++ b/BetterVR/BetterVRPlugin.Helper.cs @@ -1,7 +1,8 @@ +using HTC.UnityPlugin.Vive; +using HS2VR; using UnityEngine; using UnityEngine.UI; using UnityEngine.Events; -using HS2VR; namespace BetterVR { @@ -10,6 +11,21 @@ public static class BetterVRPluginHelper public static GameObject VROrigin; public static UnityEvent recenterVR { set; private get; } + private static Camera _VRCamera; + public static Camera VRCamera + { + get + { + if (_VRCamera == null) + { + _VRCamera = (GameObject.Find("Camera (eye)") ?? GameObject.Find("rCamera (eye)"))?.GetComponent(); + } + return _VRCamera; + } + } + + private static GameObject privacyScreen; + public enum VR_Hand { left, @@ -69,29 +85,61 @@ internal static void Init(GameObject VROrigin) /// /// Enlarge the VR camera, to make the world appear to shrink by xx% /// - public static void FixWorldScale(bool enable = true) + internal static void FixWorldScale(bool enable = true) { var viveRig = GameObject.Find("ViveRig"); if (viveRig != null) { - viveRig.transform.localScale = Vector3.one * (enable ? BetterVRPlugin.PlayerScale.Value : 1); - + viveRig.transform.localScale = Vector3.one * (enable ? BetterVRPlugin.PlayerScale : 1); } } // Moves VR camera to the player's head. internal static void ResetView() { + VRControllerInput.ClearRecordedVrOriginTransform(); + + if (VROrigin) + { + // Remove any vertical rotation. + Quaternion rotation = VROrigin.transform.rotation; + VROrigin.transform.rotation = Quaternion.Euler(0, rotation.y, 0); + } + recenterVR?.Invoke(); VRSettingUI.CameraInitAction?.Invoke(); } - private static GameObject privacyScreen; - public static void UpdatePrivacyScreen() + internal static bool LeftHandTriggerPress() + { + return ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Trigger); + } + + internal static bool LeftHandGripPress() + { + return ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip); + } + + internal static bool RightHandTriggerPress() + { + return ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Trigger); + } + + internal static bool RightHandGripPress() + { + return ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip); + } + + internal static void UpdatePrivacyScreen() { EnsurePrivacyScreen().SetActive(BetterVRPlugin.UsePrivacyScreen.Value); } + internal static Vector2 GetRightHandPadOrStickAxis() + { + return ViveInput.GetPadAxisEx(HandRole.RightHand); + } + private static GameObject EnsurePrivacyScreen() { if (privacyScreen != null) { From a9268f98de983eb5493637c496364c1f8bb5529c Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 21 Dec 2023 01:30:38 +0000 Subject: [PATCH 013/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 61 ++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index 9f7ee53..f585f9d 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -13,7 +13,6 @@ public partial class BetterVRPlugin : BaseUnityPlugin public const string GUID = "BetterVR"; public const string Version = "0.2"; - internal static new ManualLogSource Logger { get; private set; } #if DEBUG @@ -22,6 +21,9 @@ public partial class BetterVRPlugin : BaseUnityPlugin internal static bool debugLog = false; #endif + private static VRControllerInput.StripUpdater leftHandStripUpdater; + private static VRControllerInput.StripUpdater rightsHandStripUpdater; + internal void Start() { Logger = base.Logger; @@ -37,34 +39,44 @@ internal void Start() Harmony harmony_controller = new Harmony(GUID + "_controller"); VRControllerHooks.InitHooks(harmony_controller, this); - Harmony harmony_menu = new Harmony(GUID + "_menu"); + Harmony harmony_menu = new Harmony(GUID + "_menu"); VRMenuHooks.InitHooks(harmony_menu, this); - - //Potentially important Hs2 classes //ControllerManager has button input triggers, and the laser pointer //ControllerManagerSample same thing? //ShowMenuOnClick shows controller GUI //vrTest // internal static bool isOculus = XRDevice.model.Contains("Oculus"); + } - } - - - //Check for controller input changes + // Check for controller input changes internal void Update() { + if (leftHandStripUpdater == null) leftHandStripUpdater = new VRControllerInput.StripUpdater(VRControllerInput.roleL); + leftHandStripUpdater?.CheckStrip(BetterVRPlugin.GestureStrip.Value == "Left hand"); + + if (rightsHandStripUpdater == null) rightsHandStripUpdater = new VRControllerInput.StripUpdater(VRControllerInput.roleR); + rightsHandStripUpdater?.CheckStrip(BetterVRPlugin.GestureStrip.Value == "Right hand"); + // if (BetterVRPlugin.debugLog && Time.frameCount % 10 == 0) BetterVRPlugin.Logger.LogInfo($" SqueezeToTurn {SqueezeToTurn.Value} VRControllerInput.VROrigin {VRControllerInput.VROrigin}"); - //When the user squeezes the controller, apply hand rotation to headset - if (SqueezeToTurn.Value && BetterVRPluginHelper.VROrigin != null) + VRControllerInput.MaybeRestoreVrOriginTransform(); + + VRControllerInput.CheckInputForSqueezeScaling(); + + // When the user squeezes the controller, apply hand rotation to headset. + if (SqueezeToTurn.Value == "One-handed") + { + VRControllerInput.UpdateOneHandedMovements(); + } + else if (SqueezeToTurn.Value == "Two-handed") { - VRControllerInput.CheckInputForSqueezeTurn(); + VRControllerInput.UpdateTwoHandedMovements(); } - if (ViveInput.GetPressUpEx(HandRole.LeftHand, ControllerButton.AKey)) { - if (ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Trigger)) + if (ViveInput.GetPressUpEx(HandRole.LeftHand, ControllerButton.AKey) && !BetterVRPluginHelper.LeftHandGripPress()) { + if (BetterVRPluginHelper.LeftHandTriggerPress()) { BetterVRPluginHelper.ResetView(); } @@ -75,8 +87,8 @@ internal void Update() } } - if (!ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Trigger) && - ViveInput.GetPressUpEx(HandRole.RightHand, ControllerButton.AKey)) + if (ViveInput.GetPressUpEx(HandRole.RightHand, ControllerButton.AKey) && + !BetterVRPluginHelper.RightHandGripPress() && !BetterVRPluginHelper.RightHandTriggerPress()) { // Toggle player body visibility. Manager.Config.HData.Visible = !Manager.Config.HData.Visible; @@ -85,16 +97,19 @@ internal void Update() HideMonochromeP(); } + private static AIChara.ChaControl GetPlayer() + { + return Singleton.Instance?.Hscene?.GetMales()?[0]; + } + private static void HideMonochromeP() { - HScene hScene = Singleton.Instance.Hscene; - if (hScene == null) return; - var chaControl = hScene.GetMales()[0]; - if (chaControl == null) return; - chaControl.cmpSimpleBody.targetEtc.objDanTop?.SetActive(false); - chaControl.cmpSimpleBody.targetEtc.objMNPB?.SetActive(false); - chaControl.cmpSimpleBody.targetEtc.objDanSao?.SetActive(false); - chaControl.cmpSimpleBody.targetEtc.objDanTama?.SetActive(false); + var targetEtc = GetPlayer()?.cmpSimpleBody?.targetEtc; + if (targetEtc == null) return; + targetEtc.objDanTop?.SetActive(false); + targetEtc.objMNPB?.SetActive(false); + targetEtc.objDanSao?.SetActive(false); + targetEtc.objDanTama?.SetActive(false); } } } From fa1b48901d771c055e720fac587ea29289dd8546 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 21 Dec 2023 01:31:53 +0000 Subject: [PATCH 014/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 528 +++++++++++++++++++++++++++++++-- 1 file changed, 510 insertions(+), 18 deletions(-) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index 1076236..7f8a476 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -1,42 +1,534 @@ +using AIChara; using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.UI; using HTC.UnityPlugin.Vive; +using System.Collections.Generic; namespace BetterVR -{ +{ public static class VRControllerInput { internal static ViveRoleProperty roleR = ViveRoleProperty.New(HandRole.RightHand); internal static ViveRoleProperty roleL = ViveRoleProperty.New(HandRole.LeftHand); + private static bool isDraggingScale; + private static float scaleDraggingFactor; + private static Vector3? leftHandPositionDuringGripMovement = null; + private static Vector3? rightHandPositionDuringGripMovement = null; + private static Vector3? handMidpointDuringGripMovement = null; + private static Vector3? lastVrOriginPosition; + private static Quaternion? lastVrOriginRotation; + + private static Vector3 handPositionDifference { + get { + return VivePose.GetPose(roleR).pos - VivePose.GetPose(roleL).pos; + } + } + + internal static void CheckInputForSqueezeScaling() + { + bool shouldDragScale = + BetterVRPluginHelper.LeftHandTriggerPress() && BetterVRPluginHelper.LeftHandGripPress() && + BetterVRPluginHelper.RightHandTriggerPress() && BetterVRPluginHelper.RightHandGripPress(); + if (!shouldDragScale) + { + isDraggingScale = false; + if (BetterVRPluginHelper.LeftHandGripPress() + && BetterVRPluginHelper.RightHandGripPress() + && ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.AKey) + && ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.AKey)) + { + // Reset scale + BetterVRPlugin.PlayerLogScale.Value = (float)BetterVRPlugin.PlayerLogScale.DefaultValue; + } + return; + } + float handDistance = handPositionDifference.magnitude; + + if (!isDraggingScale) + { + // Start dragging scale + isDraggingScale = true; + scaleDraggingFactor = handDistance * BetterVRPlugin.PlayerScale; + return; + } + + BetterVRPlugin.PlayerScale = scaleDraggingFactor / handDistance; + } + + internal static void RecordVrOriginTransform() + { + Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; + + if (vrOrigin == null) return; + + lastVrOriginPosition = vrOrigin.position; + lastVrOriginRotation = vrOrigin.rotation; + } + + internal static void ClearRecordedVrOriginTransform() + { + lastVrOriginPosition = null; + lastVrOriginRotation = null; + } + + internal static void MaybeRestoreVrOriginTransform() + { + if (Manager.Config.HData.InitCamera) + { + return; + } + + Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; + if (vrOrigin == null) return; + + if (lastVrOriginPosition != null && lastVrOriginRotation != null) + { + // Force restore last known camera transform before animation change + // since vanilla game erroneously resets camera after changing animation + // even if the camera init option is toggled off. + vrOrigin.SetPositionAndRotation((Vector3)lastVrOriginPosition, (Quaternion)lastVrOriginRotation); + } + + // Stop attempting to restore camera transform if there is any input that might move the camera. + if (BetterVRPluginHelper.LeftHandGripPress() || BetterVRPluginHelper.RightHandGripPress() || + Mathf.Abs(BetterVRPluginHelper.GetRightHandPadOrStickAxis().x) > 0.25f || !Manager.HSceneManager.isHScene) + { + ClearRecordedVrOriginTransform(); + } + } - /// /// When user squeezes the grip, turn the camera via wrists angular veolcity /// - internal static void CheckInputForSqueezeTurn() + internal static void UpdateOneHandedMovements() + { + // Check right hand + bool shouldMoveWithRightHand = BetterVRPluginHelper.RightHandGripPress() && BetterVRPluginHelper.RightHandTriggerPress(); + var rightHandPose = VivePose.GetPose(roleR); + Vector3 rightHandAngularVelocity = VivePose.GetAngularVelocity(roleR); + UpdateMovement( + rightHandPose.pos, + Quaternion.AngleAxis(-rightHandAngularVelocity.magnitude * 180f / Mathf.PI * Time.deltaTime, rightHandAngularVelocity), + ref rightHandPositionDuringGripMovement, + shouldMoveWithRightHand); + + // Check left hand + bool shouldMoveWithLeftHand = BetterVRPluginHelper.LeftHandGripPress() && BetterVRPluginHelper.LeftHandTriggerPress(); + var leftHandPose = VivePose.GetPose(roleL); + Vector3 leftHandAngularVelocity = VivePose.GetAngularVelocity(roleL); + UpdateMovement( + leftHandPose.pos, + Quaternion.AngleAxis(-leftHandAngularVelocity.magnitude * 180f / Mathf.PI * Time.deltaTime, leftHandAngularVelocity), + ref leftHandPositionDuringGripMovement, + shouldMoveWithLeftHand); + + //Oculus input + // if (_hand == HandRole.LeftHand) + // { + // return OVRInput.Get(OVRInput.RawAxis2D.LThumbstick, OVRInput.Controller.Active); + // } + // return OVRInput.Get(OVRInput.RawAxis2D.RThumbstick, OVRInput.Controller.Active); + } + + /// + /// When user squeezes the grips, turn the camera via hand movements + /// + internal static void UpdateTwoHandedMovements() + { + Vector3 leftHandPos = VivePose.GetPose(roleL).pos; + Vector3 rightHandPos = VivePose.GetPose(roleR).pos; + Vector3 currentLocalHandMidpoint = Vector3.Lerp(leftHandPos, rightHandPos, 0.5f); + Vector3 handVelocityDifference = VivePose.GetVelocity(roleR) - VivePose.GetVelocity(roleL); + Vector3 angularVelocity = Vector3.Cross(handVelocityDifference, handPositionDifference) / handPositionDifference.sqrMagnitude * 180 / Mathf.PI; + + UpdateMovement( + currentLocalHandMidpoint, + Quaternion.Euler(angularVelocity * Time.deltaTime), + ref handMidpointDuringGripMovement, + BetterVRPluginHelper.LeftHandGripPress() && BetterVRPluginHelper.RightHandGripPress()); + } + + private static void UpdateMovement(Vector3 currentHandLocalPosition, Quaternion rotationDelta, ref Vector3? handWorldPosition, bool shouldBeActive) + { + if (!shouldBeActive) + { + handWorldPosition = null; + return; + } + + Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; + if (vrOrigin == null) return; + + if (handWorldPosition == null) + { + handWorldPosition = vrOrigin.TransformPoint(currentHandLocalPosition); + return; + } + + if (BetterVRPlugin.AllowVerticalRotation.Value) + { + vrOrigin.rotation = vrOrigin.rotation * rotationDelta; + } + else + { + vrOrigin.Rotate(0, rotationDelta.eulerAngles.y, 0, Space.Self); + } + + // Translate the VR origin so that the hand position in the game world stays constant. + vrOrigin.Translate((Vector3)handWorldPosition - vrOrigin.TransformPoint(currentHandLocalPosition), Space.World); + } + + public class StripUpdater + { + private const float STRIP_START_RANGE = 1f; + private const float STRIP_MIN_DRAG_RANGE = 0.75f; + private static readonly Color[] STRIP_INDICATOR_COLORS = + new Color[] { Color.red, new Color(1, 0.5f, 0), Color.yellow, Color.green, Color.cyan, Color.blue, Color.magenta, Color.black }; + private Canvas clothIconCanvas; + private List clothIcons = new List(); + private bool finishedLoadingClothIcons = false; + private ViveRoleProperty handRole; + private Vector3 stripStartPos; + private bool canClothe; + private StripCollider grabbedStripCollider; + private MeshRenderer stripIndicator; + + internal StripUpdater(ViveRoleProperty handRole) + { + this.handRole = handRole; + } + + internal void CheckStrip(bool enable) + { + LoadClothIcons(); + + Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; + if (vrOrigin == null) return; + + Vector3 handPos = vrOrigin.TransformPoint(VivePose.GetPose(handRole).pos); + + if (!enable || ViveInput.GetPress(handRole, ControllerButton.Grip)) + { + // Disable stripping during possible movements + grabbedStripCollider = null; + canClothe = false; + stripIndicator?.gameObject.SetActive(false); + return; + } + + if (ViveInput.GetPressUp(handRole, ControllerButton.Trigger)) + { + if (grabbedStripCollider != null && canClothe) + { + if (Vector3.Distance(handPos, stripStartPos) > STRIP_MIN_DRAG_RANGE * BetterVRPlugin.PlayerScale) + { + grabbedStripCollider.Clothe(); + } + } + canClothe = false; + grabbedStripCollider = null; + stripIndicator.gameObject.SetActive(false); + } + else if (ViveInput.GetPress(handRole, ControllerButton.Trigger)) + { + if (canClothe) + { + grabbedStripCollider = FindClosestStripCollider(handPos, STRIP_START_RANGE * BetterVRPlugin.PlayerScale, 1, 2); + UpdateStripIndicator(); + } + else if (grabbedStripCollider != null && Vector3.Distance(handPos, stripStartPos) > STRIP_MIN_DRAG_RANGE * BetterVRPlugin.PlayerScale) + { + if (Vector3.Angle(handPos - stripStartPos, grabbedStripCollider.transform.position - stripStartPos) > 90) + { + grabbedStripCollider.StripMore(); + } + else + { + grabbedStripCollider.StripLess(); + } + stripStartPos = handPos; + } + } + else + { + grabbedStripCollider = FindClosestStripCollider(handPos, STRIP_START_RANGE * BetterVRPlugin.PlayerScale, 0, 1); + UpdateStripIndicator(); + stripStartPos = handPos; + canClothe = (grabbedStripCollider == null); + } + } + + private void LoadClothIcons() + { + // The icons are not actually working for some reason as for now. + + if (finishedLoadingClothIcons || stripIndicator == null) + { + return; + } + + HSceneSprite hSceneSprite = Singleton.Instance; + if (!hSceneSprite || !hSceneSprite.objCloth || hSceneSprite.objCloth.objs == null) + { + return; + } + + while (clothIcons.Count < 8) + { + clothIcons.Add(null); + } + + if (!clothIconCanvas) + { + clothIconCanvas = new GameObject("ClothIconCanvas").AddComponent(); + clothIconCanvas.gameObject.AddComponent(); + clothIconCanvas.renderMode = RenderMode.ScreenSpaceOverlay; + clothIconCanvas.transform.SetParent(stripIndicator.transform, false); + clothIconCanvas.transform.localPosition = Vector3.zero; + clothIconCanvas.transform.localRotation = Quaternion.identity; + clothIconCanvas.transform.localScale = Vector3.one * 256f; + } + + bool waitingForIcons = false; + for (int i = 0; i < 8; i++) + { + if (clothIcons[i] != null) + { + continue; + } + + var clothButtons = hSceneSprite.objCloth.objs; + if (clothButtons == null || clothButtons.Count <= i || clothButtons[i].buttons == null || clothButtons[i].buttons.Length == 0 || clothButtons[i].buttons[0] == null) + { + waitingForIcons = true; + continue; + } + + GameObject clothIcon = GameObject.Instantiate(clothButtons[i].buttons[0].gameObject); + Object.Destroy(clothIcon.GetComponent [HarmonyPostfix, HarmonyPatch(typeof(VRSelectScene), "Start")] internal static void VRSelectScene_Start(VRSelectScene __instance) - { + { //If the pointer game object is active, then set the cursor angle - if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" VRSelectScene_Start "); + if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" VRSelectScene_Start "); //Get the character card data VRSelectManager vrMgr = Singleton.Instance; //Add Random button to GUI, next to optional button - VRMenuRandom.AppendRandomButton(__instance); - VRMenuRandom.VRSelectSceneStart(); + VRMenuRandom.AppendRandomButton(__instance); + VRMenuRandom.VRSelectSceneStart(); } [HarmonyPostfix, HarmonyPatch(typeof(GripMoveCrtl), "Start")] internal static void FindVrOrigin(GripMoveCrtl __instance) { - GameObject objVROrigin = (GameObject) typeof(GripMoveCrtl).GetField("objVROrigin", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); + GameObject objVROrigin = (GameObject)typeof(GripMoveCrtl).GetField("objVROrigin", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); if (objVROrigin) { BetterVRPluginHelper.Init(objVROrigin); } } + static bool FirstHSceneAnimationPending = true; + + [HarmonyPrefix, HarmonyPatch(typeof(HScene), nameof(HScene.Start))] + internal static void HSceneStartPatch() + { + FirstHSceneAnimationPending = true; + } + + [HarmonyPrefix, HarmonyPatch(typeof(HScene), nameof(HScene.ChangeAnimation))] + internal static void ChangeAnimationPatch() + { + if (FirstHSceneAnimationPending) + { + FirstHSceneAnimationPending = false; + // Allow the vanilla game to reset camera for the first animation. + return; + } + + if (Manager.Config.HData.InitCamera) + { + return; + } + + VRControllerInput.RecordVrOriginTransform(); + } + + [HarmonyPrefix, HarmonyPatch(typeof(HScene), "SetClothStateStartMotion")] + internal static bool SetClothStateStartMotionPatch() + { + return false; + } + [HarmonyPostfix, HarmonyPatch(typeof(VRSettingUI), "Start")] internal static void FindResetViewButton(VRSettingUI __instance) { From 8fea51eb29f27bb49b266565ea7caca5672762c4 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 22 Dec 2023 20:45:12 +0000 Subject: [PATCH 017/252] Create VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 355 ++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 BetterVR/VrController.StripUpdater.cs diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs new file mode 100644 index 0000000..5ad9ef8 --- /dev/null +++ b/BetterVR/VrController.StripUpdater.cs @@ -0,0 +1,355 @@ +using AIChara; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.UI; +using HTC.UnityPlugin.Vive; +using System.Collections.Generic; + +namespace BetterVR +{ + + public class StripUpdater + { + private const float STRIP_START_RANGE = 1f; + private const float STRIP_MIN_DRAG_RANGE = 0.75f; + private static readonly Color[] STRIP_INDICATOR_COLORS = + new Color[] { Color.blue, Color.red, Color.cyan, Color.magenta, Color.yellow, Color.green, Color.white, Color.black }; + private Canvas clothIconCanvas; + private List clothIcons = new List(); + private bool finishedLoadingClothIcons = false; + private ViveRoleProperty handRole; + private Vector3 stripStartPos; + private bool canClothe; + private StripCollider grabbedStripCollider; + private MeshRenderer stripIndicator; + + internal StripUpdater(ViveRoleProperty handRole) + { + this.handRole = handRole; + } + + internal void CheckStrip(bool enable) + { + LoadClothIcons(); + + Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; + if (vrOrigin == null) return; + + Vector3 handPos = vrOrigin.TransformPoint(VivePose.GetPose(handRole).pos); + + if (!enable || + ViveInput.GetPress(handRole, ControllerButton.Grip)) // Disable stripping during possible movements + { + grabbedStripCollider = null; + canClothe = false; + stripIndicator?.gameObject.SetActive(false); + return; + } + + if (ViveInput.GetPressUp(handRole, ControllerButton.Trigger)) + { + if (grabbedStripCollider != null && canClothe) + { + if (Vector3.Distance(handPos, stripStartPos) > STRIP_MIN_DRAG_RANGE * BetterVRPlugin.PlayerScale) + { + grabbedStripCollider.Clothe(); + } + } + canClothe = false; + grabbedStripCollider = null; + stripIndicator.gameObject.SetActive(false); + } + else if (ViveInput.GetPress(handRole, ControllerButton.Trigger)) + { + if (canClothe) + { + grabbedStripCollider = FindClosestStripCollider(handPos, STRIP_START_RANGE * BetterVRPlugin.PlayerScale, 1, 2); + UpdateStripIndicator(); + } + else if (grabbedStripCollider != null && Vector3.Distance(handPos, stripStartPos) > STRIP_MIN_DRAG_RANGE * BetterVRPlugin.PlayerScale) + { + if (Vector3.Angle(handPos - stripStartPos, grabbedStripCollider.transform.position - stripStartPos) > 90) + { + grabbedStripCollider.StripMore(); + } + else + { + grabbedStripCollider.StripLess(); + } + stripStartPos = handPos; + } + } + else + { + grabbedStripCollider = FindClosestStripCollider(handPos, STRIP_START_RANGE * BetterVRPlugin.PlayerScale, 0, 1); + UpdateStripIndicator(); + stripStartPos = handPos; + canClothe = (grabbedStripCollider == null); + } + } + + private void LoadClothIcons() + { + // The icons are not actually working for some reason as for now. + + if (finishedLoadingClothIcons || stripIndicator == null) + { + return; + } + + HSceneSprite hSceneSprite = Singleton.Instance; + if (!hSceneSprite || !hSceneSprite.objCloth || hSceneSprite.objCloth.objs == null) + { + return; + } + + while (clothIcons.Count < 8) + { + clothIcons.Add(null); + } + + if (!clothIconCanvas) + { + clothIconCanvas = new GameObject("ClothIconCanvas").AddComponent(); + clothIconCanvas.gameObject.AddComponent(); + clothIconCanvas.renderMode = RenderMode.ScreenSpaceOverlay; + clothIconCanvas.transform.SetParent(stripIndicator.transform, false); + clothIconCanvas.transform.localPosition = Vector3.zero; + clothIconCanvas.transform.localRotation = Quaternion.identity; + clothIconCanvas.transform.localScale = Vector3.one * 256f; + } + + bool waitingForIcons = false; + for (int i = 0; i < 8; i++) + { + if (clothIcons[i] != null) + { + continue; + } + + var clothButtons = hSceneSprite.objCloth.objs; + if (clothButtons == null || clothButtons.Count <= i || clothButtons[i].buttons == null || clothButtons[i].buttons.Length == 0 || clothButtons[i].buttons[0] == null) + { + waitingForIcons = true; + continue; + } + + GameObject clothIcon = GameObject.Instantiate(clothButtons[i].buttons[0].gameObject); + Object.Destroy(clothIcon.GetComponent internal static void UpdateOneHandedMovements() { + Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; + if (!vrOrigin) return; + // Check right hand bool shouldMoveWithRightHand = BetterVRPluginHelper.RightHandGripPress() && BetterVRPluginHelper.RightHandTriggerPress(); var rightHandPose = VivePose.GetPose(roleR); - Vector3 rightHandAngularVelocity = VivePose.GetAngularVelocity(roleR); + Vector3 rightHandAngularVelocity = + lastRightHandRotation == null ? + Vector3.zero : + GetAngularVelocityInRoomCoordinates(roleR, rightHandPose.rot * Quaternion.Inverse((Quaternion) lastRightHandRotation)); + lastRightHandRotation = rightHandPose.rot; UpdateMovement( rightHandPose.pos, Quaternion.AngleAxis(-rightHandAngularVelocity.magnitude * 180f / Mathf.PI * Time.deltaTime, rightHandAngularVelocity), @@ -117,7 +117,11 @@ internal static void UpdateOneHandedMovements() // Check left hand bool shouldMoveWithLeftHand = BetterVRPluginHelper.LeftHandGripPress() && BetterVRPluginHelper.LeftHandTriggerPress(); var leftHandPose = VivePose.GetPose(roleL); - Vector3 leftHandAngularVelocity = VivePose.GetAngularVelocity(roleL); + Vector3 leftHandAngularVelocity = + lastLeftHandRotation == null ? + Vector3.zero : + GetAngularVelocityInRoomCoordinates(roleL, leftHandPose.rot * Quaternion.Inverse((Quaternion)lastLeftHandRotation)); + lastLeftHandRotation = leftHandPose.rot; UpdateMovement( leftHandPose.pos, Quaternion.AngleAxis(-leftHandAngularVelocity.magnitude * 180f / Mathf.PI * Time.deltaTime, leftHandAngularVelocity), @@ -140,17 +144,21 @@ internal static void UpdateTwoHandedMovements() Vector3 leftHandPos = VivePose.GetPose(roleL).pos; Vector3 rightHandPos = VivePose.GetPose(roleR).pos; Vector3 currentLocalHandMidpoint = Vector3.Lerp(leftHandPos, rightHandPos, 0.5f); - Vector3 handVelocityDifference = VivePose.GetVelocity(roleR) - VivePose.GetVelocity(roleL); - Vector3 angularVelocity = Vector3.Cross(handVelocityDifference, handPositionDifference) / handPositionDifference.sqrMagnitude * 180 / Mathf.PI; + Vector3 handPositionDifference = rightHandPos - leftHandPos; + Quaternion rotationDelta = + lastHandPositionDifference == null ? + Quaternion.identity : + Quaternion.FromToRotation(handPositionDifference, (Vector3)lastHandPositionDifference); + lastHandPositionDifference = handPositionDifference; UpdateMovement( currentLocalHandMidpoint, - Quaternion.Euler(angularVelocity * Time.deltaTime), + rotationDelta, ref handMidpointDuringGripMovement, BetterVRPluginHelper.LeftHandGripPress() && BetterVRPluginHelper.RightHandGripPress()); } - private static void UpdateMovement(Vector3 currentHandLocalPosition, Quaternion rotationDelta, ref Vector3? handWorldPosition, bool shouldBeActive) + private static void UpdateMovement(Vector3 currentHandLocalPosition, Quaternion localRotationDelta, ref Vector3? handWorldPosition, bool shouldBeActive) { if (!shouldBeActive) { @@ -169,366 +177,38 @@ private static void UpdateMovement(Vector3 currentHandLocalPosition, Quaternion if (BetterVRPlugin.AllowVerticalRotation.Value) { - vrOrigin.rotation = vrOrigin.rotation * rotationDelta; + vrOrigin.rotation = vrOrigin.rotation * localRotationDelta; } else { - vrOrigin.Rotate(0, rotationDelta.eulerAngles.y, 0, Space.Self); + vrOrigin.Rotate(0, localRotationDelta.eulerAngles.y, 0, Space.Self); } // Translate the VR origin so that the hand position in the game world stays constant. vrOrigin.Translate((Vector3)handWorldPosition - vrOrigin.TransformPoint(currentHandLocalPosition), Space.World); } - - public class StripUpdater - { - private const float STRIP_START_RANGE = 1f; - private const float STRIP_MIN_DRAG_RANGE = 0.75f; - private static readonly Color[] STRIP_INDICATOR_COLORS = - new Color[] { Color.red, new Color(1, 0.5f, 0), Color.yellow, Color.green, Color.cyan, Color.blue, Color.magenta, Color.black }; - private Canvas clothIconCanvas; - private List clothIcons = new List(); - private bool finishedLoadingClothIcons = false; - private ViveRoleProperty handRole; - private Vector3 stripStartPos; - private bool canClothe; - private StripCollider grabbedStripCollider; - private MeshRenderer stripIndicator; - - internal StripUpdater(ViveRoleProperty handRole) - { - this.handRole = handRole; - } - - internal void CheckStrip(bool enable) - { - LoadClothIcons(); - - Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; - if (vrOrigin == null) return; - - Vector3 handPos = vrOrigin.TransformPoint(VivePose.GetPose(handRole).pos); - - if (!enable || ViveInput.GetPress(handRole, ControllerButton.Grip)) - { - // Disable stripping during possible movements - grabbedStripCollider = null; - canClothe = false; - stripIndicator?.gameObject.SetActive(false); - return; - } - - if (ViveInput.GetPressUp(handRole, ControllerButton.Trigger)) - { - if (grabbedStripCollider != null && canClothe) - { - if (Vector3.Distance(handPos, stripStartPos) > STRIP_MIN_DRAG_RANGE * BetterVRPlugin.PlayerScale) - { - grabbedStripCollider.Clothe(); - } - } - canClothe = false; - grabbedStripCollider = null; - stripIndicator.gameObject.SetActive(false); - } - else if (ViveInput.GetPress(handRole, ControllerButton.Trigger)) - { - if (canClothe) - { - grabbedStripCollider = FindClosestStripCollider(handPos, STRIP_START_RANGE * BetterVRPlugin.PlayerScale, 1, 2); - UpdateStripIndicator(); - } - else if (grabbedStripCollider != null && Vector3.Distance(handPos, stripStartPos) > STRIP_MIN_DRAG_RANGE * BetterVRPlugin.PlayerScale) - { - if (Vector3.Angle(handPos - stripStartPos, grabbedStripCollider.transform.position - stripStartPos) > 90) - { - grabbedStripCollider.StripMore(); - } - else - { - grabbedStripCollider.StripLess(); - } - stripStartPos = handPos; - } - } - else - { - grabbedStripCollider = FindClosestStripCollider(handPos, STRIP_START_RANGE * BetterVRPlugin.PlayerScale, 0, 1); - UpdateStripIndicator(); - stripStartPos = handPos; - canClothe = (grabbedStripCollider == null); - } - } - - private void LoadClothIcons() - { - // The icons are not actually working for some reason as for now. - - if (finishedLoadingClothIcons || stripIndicator == null) - { - return; - } - - HSceneSprite hSceneSprite = Singleton.Instance; - if (!hSceneSprite || !hSceneSprite.objCloth || hSceneSprite.objCloth.objs == null) - { - return; - } - - while (clothIcons.Count < 8) - { - clothIcons.Add(null); - } - - if (!clothIconCanvas) - { - clothIconCanvas = new GameObject("ClothIconCanvas").AddComponent(); - clothIconCanvas.gameObject.AddComponent(); - clothIconCanvas.renderMode = RenderMode.ScreenSpaceOverlay; - clothIconCanvas.transform.SetParent(stripIndicator.transform, false); - clothIconCanvas.transform.localPosition = Vector3.zero; - clothIconCanvas.transform.localRotation = Quaternion.identity; - clothIconCanvas.transform.localScale = Vector3.one * 256f; - } - - bool waitingForIcons = false; - for (int i = 0; i < 8; i++) - { - if (clothIcons[i] != null) - { - continue; - } - - var clothButtons = hSceneSprite.objCloth.objs; - if (clothButtons == null || clothButtons.Count <= i || clothButtons[i].buttons == null || clothButtons[i].buttons.Length == 0 || clothButtons[i].buttons[0] == null) - { - waitingForIcons = true; - continue; - } - - GameObject clothIcon = GameObject.Instantiate(clothButtons[i].buttons[0].gameObject); - Object.Destroy(clothIcon.GetComponent internal static GameObject GetHand(VR_Hand hand) { if (hand == VR_Hand.left) return GetLeftHand(); @@ -49,31 +158,21 @@ internal static GameObject GetHand(VR_Hand hand) return null; } - /// /// Get The left hand controller vr game object /// internal static GameObject GetLeftHand() { - var leftHand = GameObject.Find("ViveControllers/Left"); - if (leftHand == null) leftHand = GameObject.Find("Controller (left)"); - if (leftHand == null) return null; - - if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" GetLeftHand id {leftHand.GetInstanceID()}"); - - return leftHand.gameObject; + var leftHand = GameObject.Find("ViveControllers/Left") ?? GameObject.Find("Controller (left)"); + if (leftHand && BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" GetLeftHand id {leftHand.GetInstanceID()}"); + return leftHand; } - internal static GameObject GetRightHand() { - var rightHand = GameObject.Find("ViveControllers/Right"); - if (rightHand == null) rightHand = GameObject.Find("Controller (right)"); - if (rightHand == null) return null; - - if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" GetRightHand id {rightHand.GetInstanceID()}"); - - return rightHand.gameObject; + var rightHand = GameObject.Find("ViveControllers/Right") ?? GameObject.Find("Controller (right)"); + if (rightHand && BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" GetRightHand id {rightHand.GetInstanceID()}"); + return rightHand; } /// @@ -82,21 +181,17 @@ internal static GameObject GetRightHand() internal static void Init(GameObject VROrigin) { BetterVRPluginHelper.VROrigin = VROrigin; - BetterVRPluginHelper.FixWorldScale(); - BetterVRPluginHelper.UpdatePrivacyScreen(); + FixWorldScale(); } - /// /// Enlarge the VR camera, to make the world appear to shrink by xx% /// internal static void FixWorldScale(bool enable = true) { var viveRig = GameObject.Find("ViveRig"); - if (viveRig != null) - { - viveRig.transform.localScale = Vector3.one * (enable ? BetterVRPlugin.PlayerScale : 1); - } + if (viveRig == null) return; + viveRig.transform.localScale = Vector3.one * (enable ? BetterVRPlugin.PlayerScale : 1); } // Moves VR camera to the player's head. @@ -115,34 +210,118 @@ internal static void ResetView() VRSettingUI.CameraInitAction?.Invoke(); } - private static void LoadGloves() + internal static void CyclePlayerPDisplayMode() + { + // Sync display mode before changing it. + if (!Manager.Config.HData.Son) pDisplayMode = 0; + // Cycle player part display mode. + pDisplayMode = (pDisplayMode + 1) % 3; + // Toggle player part visibility. + UpdatePDisplay(); + UpdatePlayerColliderActivity(); + } + + internal static void UpdatePlayerColliderActivity() + { + var player = BetterVRPlugin.GetPlayer(); + if (player == null) return; + var colliders = player.objTop.GetComponentsInChildren(); + foreach (var collider in colliders) + { + if (HAND_NAME_MATCHER.IsMatch(collider.name)) + { + collider.enabled = Manager.Config.HData.Visible; + } + else if (P_NAME_MATCHER.IsMatch(collider.name)) + { + collider.enabled = Manager.Config.HData.Son; + } + } + } + + private static void UpdatePDisplay() { - if (gloves != null) return; - var glovesPrefab = AssetBundleManager.LoadAssetBundle(AssetBundleNames.Chara00Mo_Gloves_00)?.Bundle?.LoadAsset( - "assets/illusion/assetbundle/prefabs/chara/male/00/mo_gloves_00/p_cm_glove_gunte.prefab"); - if (!glovesPrefab) return; - gloves = GameObject.Instantiate(glovesPrefab); - gloves.GetComponentInChildren()?.GetOrAddComponent(); + Manager.Config.HData.Son = (pDisplayMode != 0); + + var player = BetterVRPlugin.GetPlayer(); + if (!player || !player.loadEnd) return; + + bool shouldUseSimpleP = Manager.Config.HData.Son && pDisplayMode == 2; + bool shouldUseRegularP = Manager.Config.HData.Son && pDisplayMode == 1; + + var simpleBodyEtc = player.cmpSimpleBody?.targetEtc; + GameObject simpleBody = simpleBodyEtc?.objBody; + if (simplePClone != null) + { + if (!shouldUseSimpleP || simpleBody == null || simplePClone.transform.parent != simpleBody.transform.parent) + { + GameObject.Destroy(simplePClone); + simplePClone = null; + } + + } + + if (shouldUseSimpleP && simplePClone == null) + { + GameObject simpleP = simpleBodyEtc?.objDanTop; + if (simpleBody && simpleP) + { + simplePClone = GameObject.Instantiate(simpleP, simpleP.transform.parent); + simplePClone.transform.SetPositionAndRotation(simpleP.transform.position, simpleP.transform.rotation); + simplePClone.transform.localScale = simpleP.transform.localScale; + // Reparent so that it is a sibling instead of a child of simpleBody and + // can be displayed even if simpleBody is hidden. + simplePClone.transform.SetParent(simpleBody.transform.parent, worldPositionStays: true); + var renderers = simplePClone.GetComponentsInChildren(); + foreach (var renderer in renderers) + { + renderer.enabled = true; + renderer.GetOrAddComponent(); + } + } + } + + simplePClone?.SetActive(shouldUseSimpleP); + + // Hide the original part now that there is a clone. + var tamaRenderer = simpleBodyEtc?.objDanTama?.GetComponentInChildren(); + if (tamaRenderer) tamaRenderer.enabled = false; + + var saoRenderer = simpleBodyEtc?.objDanSao?.GetComponentInChildren(); + if (saoRenderer) saoRenderer.enabled = false; + + var regularBodyEtc = player.cmpBody?.targetEtc; + if (regularBodyEtc != null) + { + regularBodyEtc.objMNPB?.SetActive(shouldUseRegularP); + regularBodyEtc.objDanTop?.SetActive(shouldUseRegularP); + regularBodyEtc.objDanSao?.SetActive(shouldUseRegularP); + regularBodyEtc.objDanTama?.SetActive(shouldUseRegularP); + } } - public static GameObject GetLeftGlove() + internal static void FinishH() { - LoadGloves(); - if (gloves == null) return null; - var glove = gloves.transform.FindLoop("cf_J_ArmLow01_L")?.gameObject; - if (!glove) return null; - glove.GetOrAddComponent().Init(HandRole.LeftHand); - return glove; + var fCtrl = Singleton.Instance; + var sprite = Singleton.Instance; + var anim = Singleton.Instance?.Hscene?.GetProcBase(); + if (!fCtrl || !sprite || anim == null || fCtrl.loopType < 0) return; + + if (fCtrl.loopType == 0 || + anim is Aibu || anim is Houshi || anim is Spnking || anim is Masturbation || anim is Peeping || anim is Les) + { + sprite.OnClickFinish(); + } + else + { + sprite.OnClickFinishSame(); + } } - public static GameObject GetRightGlove() + internal static void TryInitializeGloves() { - LoadGloves(); - if (gloves == null) return null; - var glove = gloves.transform.FindLoop("cf_J_ArmLow01_R")?.gameObject; - if (!glove) return null; - glove.GetOrAddComponent().Init(HandRole.RightHand, -1); - return glove; + if (!_leftGlove) _leftGlove = VRGlove.CreateLeftGlove(); + if (!_rightGlove) _rightGlove = VRGlove.CreateRightGlove(); } internal static bool LeftHandTriggerPress() @@ -165,9 +344,10 @@ internal static bool RightHandGripPress() return ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip); } - internal static void UpdatePrivacyScreen() + internal static void UpdatePrivacyScreen(Color? color = null) { - EnsurePrivacyScreen().SetActive(BetterVRPlugin.UsePrivacyScreen.Value); + EnsurePrivacyScreen().gameObject.SetActive(BetterVRPlugin.UsePrivacyScreen.Value); + if (color != null) privacyScreen.color = (Color) color; } internal static Vector2 GetRightHandPadStickCombinedOutput() @@ -178,6 +358,16 @@ internal static Vector2 GetRightHandPadStickCombinedOutput() return output; } + internal static Transform FindLeftControllerRenderModel(out Vector3 center) + { + return FindControllerRenderModel(GetLeftHand(), out center); + } + + internal static Transform FindRightControllerRenderModel(out Vector3 center) + { + return FindControllerRenderModel(GetRightHand(), out center); + } + internal static Transform FindControllerRenderModel(GameObject hand, out Vector3 center) { center = Vector3.zero; @@ -200,109 +390,35 @@ internal static void UpdateControllersVisibilty() UpdateControllerVisibilty(FindControllerRenderModel(GetRightHand(), out var rCenter)); } - internal static void UpdateHandsVisibility() - { - UpdateHandVisibility(BetterVRPluginHelper.GetLeftHand(), ref leftGlove); - UpdateHandVisibility(BetterVRPluginHelper.GetRightHand(), ref rightGlove); - } - private static void UpdateControllerVisibilty(Transform renderModel) { if (!renderModel) return; bool shouldShowController = - leftGlove == null || !leftGlove.activeSelf || - rightGlove == null || !rightGlove.activeSelf || - (Manager.Config.HData.Visible && !Manager.Config.HData.SimpleBody) || - !BetterVRPlugin.GetPlayer(); + !VRGlove.isShowingGloves || + BetterVRPlugin.HandDisplay.Value == "Controllers" || + BetterVRPlugin.HandDisplay.Value == "GlovesAndControllers"; var renderers = renderModel.GetComponentsInChildren(); - if (renderers == null) return; - foreach (var renderer in renderers) renderer.enabled = shouldShowController; } - private static void UpdateHandVisibility(GameObject hand, ref GameObject glove) - { - Transform renderModel = BetterVRPluginHelper.FindControllerRenderModel(hand, out Vector3 center); - if (glove != null) - { - if (renderModel == null || glove.gameObject == null) glove = null; - } - - if (glove == null && renderModel != null) - { - glove = hand.name.Contains("ight") ? GetRightGlove() : GetLeftGlove(); - if (glove) - { - glove.name = hand.name + "_simpleGlove"; - } - else - { - glove = GameObject.CreatePrimitive(PrimitiveType.Sphere); - glove.GetOrAddComponent(); - glove.AddComponent(); - glove.name = hand.name + "_simpleSphere"; - } - glove.gameObject.SetActive(false); - GameObject.DontDestroyOnLoad(glove.gameObject); - } - - bool shouldShowHand = BetterVRPlugin.ShowHand.Value && glove != null && renderModel != null; - bool isShowingHand = glove != null && glove.activeSelf; - - if (shouldShowHand != isShowingHand) UpdateControllerVisibilty(renderModel); - - if (!glove) return; - - glove.gameObject.SetActive(shouldShowHand); - - if (shouldShowHand) - { - if (glove.transform.parent != renderModel.parent && !VRControllerInput.repositioningHand) - { - glove.transform.parent = renderModel.parent; - } - - if (glove.transform.parent != null) - { - // The render model may have been changed by the system so the simple renderer may need to be repositioned too. - bool isRightHand = glove.name.Contains("ight"); - Vector3 offsetFromCenter; - if (glove.name == hand.name + "_simpleSphere") - { - glove.transform.localScale = new Vector3(0.04f, 0.06f, 0.09f); - glove.transform.localRotation = Quaternion.identity; - offsetFromCenter = (isRightHand ? Vector3.right : Vector3.left) * 0.04f; - } - else - { - glove.transform.localScale = Vector3.one * BetterVRPlugin.HandScale.Value; - glove.transform.localRotation = - isRightHand ? BetterVRPlugin.RightHandRotation.Value : BetterVRPlugin.LeftHandRotation.Value; - offsetFromCenter = isRightHand ? BetterVRPlugin.RightHandOffset.Value : BetterVRPlugin.LeftHandOffset.Value; - } - glove.transform.position = center + renderModel.transform.TransformVector(offsetFromCenter); - } - } - } - - private static GameObject EnsurePrivacyScreen() { - if (privacyScreen != null) + private static Image EnsurePrivacyScreen() { + if (privacyScreen && privacyScreen.gameObject && privacyScreen.transform.parent) { return privacyScreen; } - privacyScreen = new GameObject("PrivacyMode"); - Canvas privacyCanvas = privacyScreen.AddComponent(); + Canvas privacyCanvas = new GameObject("PrivacyCanvas").AddComponent(); privacyCanvas.renderMode = RenderMode.ScreenSpaceOverlay; privacyCanvas.sortingOrder = 30000; - GameObject privacyOverlay = new GameObject("Overlay"); - privacyOverlay.transform.SetParent(privacyScreen.transform); - Image image = privacyOverlay.AddComponent(); - image.rectTransform.sizeDelta = new Vector2((float)(Screen.width * 4), (float)(Screen.height * 4)); - image.color = Color.black; - UnityEngine.Object.DontDestroyOnLoad(privacyScreen); + GameObject privacyOverlay = new GameObject("PrivacySreen"); + privacyOverlay.transform.SetParent(privacyCanvas.transform); + privacyScreen = privacyOverlay.AddComponent(); + privacyScreen.transform.SetParent(privacyCanvas.transform); + privacyScreen.rectTransform.sizeDelta = new Vector2((float)(Screen.width * 4), (float)(Screen.height * 4)); + privacyScreen.color = Color.black; + Object.DontDestroyOnLoad(privacyCanvas.gameObject); return privacyScreen; } @@ -325,7 +441,7 @@ void Update() UpdateControllersVisibilty(); - GameObject.Destroy(this); + Destroy(this); } } } From 96b90ddcd365797a58e837edd3de5c94aeec5d87 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 1 Jan 2024 03:59:01 +0000 Subject: [PATCH 042/252] Create GaugeHitIndicator.cs --- BetterVR/GaugeHitIndicator.cs | 124 ++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 BetterVR/GaugeHitIndicator.cs diff --git a/BetterVR/GaugeHitIndicator.cs b/BetterVR/GaugeHitIndicator.cs new file mode 100644 index 0000000..67b88da --- /dev/null +++ b/BetterVR/GaugeHitIndicator.cs @@ -0,0 +1,124 @@ +using TMPro; +using UnityEngine; + +namespace BetterVR +{ + internal class GaugeHitIndicator + { + private float smoothGaugeHit = 0; + private float acceleration; + private Vector3 headIndicatorVelocity = Vector3.zero; + private GameObject _headIndicator = null; + private GameObject _leftHandIndicator = null; + private GameObject _rightHandIndicator = null; + private GameObject headIndicator + { + get + { + if (!_headIndicator) _headIndicator = CreateIndicator(BetterVRPluginHelper.VROrigin?.transform); + return _headIndicator; + } + } + private GameObject leftHandIndicator + { + get + { + if (!_leftHandIndicator) _leftHandIndicator = CreateIndicator(BetterVRPluginHelper.leftCursorAttach); + return _leftHandIndicator; + } + } + private GameObject rightHandIndicator + { + get + { + if (!_rightHandIndicator) _rightHandIndicator = CreateIndicator(BetterVRPluginHelper.rightCursorAttach); + return _rightHandIndicator; + } + } + + internal void ShowIfGaugeIsHit() + { + if (!IsGaugeHit()) return; + if (!leftHandIndicator || !rightHandIndicator || !headIndicator) return; + + smoothGaugeHit = Mathf.SmoothDamp(smoothGaugeHit, 1, ref acceleration, 0.125f); + leftHandIndicator.SetActive(true); + rightHandIndicator.SetActive(true); + headIndicator.SetActive(true); + + UpdateIndicatorSize(); + var camera = BetterVRPluginHelper.VRCamera; + var vrOrigin = BetterVRPluginHelper.VROrigin; + if (camera == null || vrOrigin == null) return; + leftHandIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); + rightHandIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); + headIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); + } + + internal void UpdateIndicators() + { + var camera = BetterVRPluginHelper.VRCamera; + var vrOrigin = BetterVRPluginHelper.VROrigin; + if (camera && vrOrigin) + { + headIndicator.transform.position = + Vector3.SmoothDamp( + headIndicator.transform.position, + camera.transform.TransformPoint(0, 0.3125f, 0.75f), + ref headIndicatorVelocity, + 1f); + } + + if (IsGaugeHit()) return; + if (!leftHandIndicator || !rightHandIndicator || !headIndicator) return; + + if (!leftHandIndicator.activeSelf && !rightHandIndicator.activeSelf && !headIndicator.activeSelf) + { + smoothGaugeHit = 0; + return; + } + + smoothGaugeHit = Mathf.SmoothDamp(smoothGaugeHit, -0.125f, ref acceleration, 0.25f); + if (smoothGaugeHit < 0) + { + smoothGaugeHit = 0; + headIndicator.SetActive(false); + leftHandIndicator.SetActive(false); + rightHandIndicator.SetActive(false); + } + else + { + UpdateIndicatorSize(); + } + } + + private bool IsGaugeHit() + { + return Singleton.Instance?.isGaugeHit ?? false; + } + + private void UpdateIndicatorSize() + { + if (headIndicator) headIndicator.transform.localScale = + Vector3.one * 0.03f * smoothGaugeHit; + if (leftHandIndicator) leftHandIndicator.transform.localScale = + Vector3.one * 0.02f * smoothGaugeHit; + if (rightHandIndicator) rightHandIndicator.transform.localScale = + Vector3.one * 0.02f * smoothGaugeHit; + } + + private static GameObject CreateIndicator(Transform cursorAttach) + { + if (!cursorAttach) return null; + var textMesh = + new GameObject().AddComponent().gameObject.AddComponent(); + textMesh.transform.SetParent(cursorAttach); + textMesh.transform.localPosition = Vector3.back * 0.0625f; + textMesh.text = "\u2665"; + textMesh.fontSize = 16; + textMesh.color = new Color(1, 0.25f, 0.25f); + textMesh.alignment = TextAlignmentOptions.Center; + return textMesh.gameObject; + } + } +} From 7d55ff1b1a5a0b3b3c63be0855543336b0382647 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 1 Jan 2024 03:59:31 +0000 Subject: [PATCH 043/252] Create HandHeldToy.cs --- BetterVR/HandHeldToy.cs | 170 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 BetterVR/HandHeldToy.cs diff --git a/BetterVR/HandHeldToy.cs b/BetterVR/HandHeldToy.cs new file mode 100644 index 0000000..2becff0 --- /dev/null +++ b/BetterVR/HandHeldToy.cs @@ -0,0 +1,170 @@ +using HTC.UnityPlugin.Vive; +using UnityEngine; + +namespace BetterVR +{ + public class HandHeldToy : MonoBehaviour + { + private const float RADIUS = 0.15f; + private const float HEIGHT = 3f; + private const float GRAB_RANGE = 0.5f; + + private int mode = 0; + private GameObject simpleModel; + private GameObject fullModel; + private HSpeedGesture hSpeedGesture; + + internal DynamicBoneCollider collider { get; private set; } + + void Awake() + { + CreateSimpleModel(); + TryCreateFullModel(); + CreateCollider(); + simpleModel.SetActive(false); + fullModel?.SetActive(false); + collider.enabled = false; + hSpeedGesture.enabled = false; + } + + void Update() + { + if (mode == 0) return; + + if (ViveInput.GetPressDownEx(HandRole.LeftHand, ControllerButton.Grip) && !VRControllerInput.isDraggingScale) + { + AttachAndBringToRangeOf(BetterVRPluginHelper.FindLeftControllerRenderModel(out var center)); + hSpeedGesture.roleProperty = VRControllerInput.roleL; + } + else if (ViveInput.GetPressDownEx(HandRole.RightHand, ControllerButton.Grip) && !VRControllerInput.isDraggingScale) + { + hSpeedGesture.roleProperty = VRControllerInput.roleR; + AttachAndBringToRangeOf(BetterVRPluginHelper.FindRightControllerRenderModel(out var center)); + } + else if ( + VRControllerInput.isDraggingScale || + (!ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip) && + !ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip))) + { + transform.SetParent(null, worldPositionStays: true); + hSpeedGesture.enabled = false; + } + else + { + hSpeedGesture.enabled = (mode != 0); + } + } + + internal void CycleMode(bool isRightHand) + { + mode = (mode + 1) % 3; + + if (mode == 1) + { + // Bring the newly appeared object into range of hand. + if (isRightHand) + { + AttachAndBringToRangeOf(BetterVRPluginHelper.FindRightControllerRenderModel(out var center)); + } + else + { + AttachAndBringToRangeOf(BetterVRPluginHelper.FindLeftControllerRenderModel(out var center)); + } + transform.SetParent(null, worldPositionStays: true); + } + + TryCreateFullModel(); + if (!fullModel && mode == 1) mode = 2; + + fullModel?.SetActive(mode == 1); + simpleModel.SetActive(mode == 2); + collider.enabled = (mode != 0); + + BetterVRPluginHelper.UpdatePlayerColliderActivity(); + } + + private void CreateSimpleModel() + { + simpleModel = GameObject.CreatePrimitive(PrimitiveType.Cylinder); + simpleModel.transform.parent = transform; + simpleModel.transform.localScale = new Vector3(RADIUS * 2, HEIGHT / 2 - RADIUS, RADIUS * 2); + simpleModel.transform.localPosition = Vector3.zero; + simpleModel.GetOrAddComponent().GetOrAddComponent(); + Destroy(simpleModel.GetComponent()); + + var frontCap = GameObject.CreatePrimitive(PrimitiveType.Sphere); + frontCap.transform.parent = simpleModel.transform; + frontCap.transform.localScale = new Vector3(1, simpleModel.transform.localScale.x / simpleModel.transform.localScale.y, 1); + frontCap.transform.localPosition = Vector3.up; + frontCap.GetOrAddComponent().GetOrAddComponent(); + Destroy(frontCap.GetComponent()); + + var rearCap = GameObject.CreatePrimitive(PrimitiveType.Sphere); + rearCap.transform.parent = simpleModel.transform; + rearCap.transform.localScale = new Vector3(1, simpleModel.transform.localScale.x / simpleModel.transform.localScale.y, 1); + rearCap.transform.localPosition = Vector3.down; + rearCap.GetOrAddComponent().GetOrAddComponent(); + Destroy(rearCap.GetComponent()); + + hSpeedGesture = gameObject.AddComponent(); + hSpeedGesture.capsuleStart = rearCap.transform; + hSpeedGesture.capsuleEnd = frontCap.transform; + hSpeedGesture.radius = RADIUS; + } + + private void TryCreateFullModel() + { + if (fullModel) return; + + GameObject prefab = null; + try + { + prefab = AssetBundleManager.LoadAssetBundle(AssetBundleNames.HH_Item01)?.Bundle?.LoadAsset( + "assets/illusion/assetbundle/hscene/h/h_item/01/p_item_vibe.prefab"); + } catch { + BetterVRPlugin.Logger.LogWarning("Cannot find toy prefab"); + return; + } + + if (!prefab) return; + + var renderer = prefab.GetComponentInChildren(); + if (renderer != null) + { + fullModel = GameObject.Instantiate(renderer.gameObject); + } + else + { + var skinnedMeshRenderer = prefab.GetComponentInChildren(); + if (!skinnedMeshRenderer) return; + + fullModel = GameObject.Instantiate(skinnedMeshRenderer.gameObject); + var mesh = skinnedMeshRenderer.sharedMesh; + var materials = skinnedMeshRenderer.materials; + Destroy(fullModel.GetComponent()); + fullModel.AddComponent().mesh = mesh; + fullModel.AddComponent().materials = materials; + } + + fullModel.transform.parent = transform; + fullModel.transform.position += transform.position - fullModel.GetComponent().bounds.center; + } + + private void CreateCollider() + { + collider = gameObject.AddComponent(); + collider.m_Direction = DynamicBoneColliderBase.Direction.Y; + collider.m_Radius = RADIUS; + collider.m_Height = HEIGHT; + } + + private void AttachAndBringToRangeOf(Transform parent) + { + transform.SetParent(parent, worldPositionStays: true); + if (parent != null && transform.localPosition.magnitude > GRAB_RANGE) + { + transform.localPosition = Vector3.zero; + } + } + } +} From 5c660ce268de8a0362ef17f025c8164e27e0ad46 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 1 Jan 2024 03:59:51 +0000 Subject: [PATCH 044/252] Create HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 100 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 BetterVR/HSpeedGesture.cs diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs new file mode 100644 index 0000000..1617606 --- /dev/null +++ b/BetterVR/HSpeedGesture.cs @@ -0,0 +1,100 @@ +using HTC.UnityPlugin.Vive; +using System.Text.RegularExpressions; +using UnityEngine; + +namespace BetterVR +{ + public class HSpeedGesture : MonoBehaviour + { + private const float BASE_SPEED = 0.01f; + private const float SPEED_FACTOR = 2f; + private const float LOOP_CHANGE_THRESHOLD = 0.5f; + private static readonly Regex INTERACTING_COLLIDER_NAME_MATCHER = + new Regex(@"mune|Mune|Chest|chest|agina|okan"); + + internal ViveRoleProperty roleProperty; + internal Transform capsuleStart; + internal Transform capsuleEnd; + internal float radius = 0.25f; + + private float smoothTargetSpeed = 0; + private float acceleration = 0; + private bool isEffective; + + void FixedUpdate() + { + if (!BetterVRPlugin.UseHandSpeedForHSpeed.Value) return; + if (!capsuleStart || !capsuleEnd) return; + var hCtrl = Singleton.Instance; + if (!hCtrl) return; + + float deviceSpeed = VivePose.GetVelocity(roleProperty).magnitude; + if (!isEffective) smoothTargetSpeed = hCtrl.speed; + isEffective = ShouldBeEffective(hCtrl, deviceSpeed); + if (!isEffective) return; + + float targetSpeed = deviceSpeed * SPEED_FACTOR + BASE_SPEED; + if (hCtrl.loopType == 1) targetSpeed *= 2; + targetSpeed = Mathf.Clamp(targetSpeed, 0, 2); + + float speedDivider = 1f; + + float damper = 0.25f; + if (hCtrl.isGaugeHit) + { + // Allow staying in gauge hit zone longer to avoid voice flickering. + damper = 1.5f; + } + else if (hCtrl.loopType == 1 && smoothTargetSpeed < speedDivider) + { + // Attempting to go from fast mode to slow mode, increase damper to enforce delay. + damper = 0.75f; + } + + smoothTargetSpeed = Mathf.SmoothDamp( + smoothTargetSpeed, targetSpeed, ref acceleration, smoothTime:damper); + + switch (hCtrl.loopType) + { + case -1: + smoothTargetSpeed = 0; + break; + case 0: + hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, 0, speedDivider - 0.01f); + // Check whether to move onto loop stage 1 + if (smoothTargetSpeed > speedDivider + LOOP_CHANGE_THRESHOLD) hCtrl.speed = speedDivider + LOOP_CHANGE_THRESHOLD; + break; + case 1: + hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, speedDivider + 0.01f, 2f); + // Check whether to move back to loop stage 0 + if (smoothTargetSpeed < speedDivider - LOOP_CHANGE_THRESHOLD) hCtrl.speed = speedDivider - LOOP_CHANGE_THRESHOLD; + break; + default: + hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, 0, 2f); + break; + } + + // BetterVRPlugin.Logger.LogWarning( + // "H Loop type: " + hCtrl.loopType + " current speed: " + hCtrl.speed + + // " smooth target speed: " + smoothTargetSpeed + " target speed: " + targetSpeed); + + BetterVRPluginHelper.gaugeHitIndicator.ShowIfGaugeIsHit(); + } + + private bool ShouldBeEffective(HSceneFlagCtrl ctrl, float deviceSpeed) + { + // Keep control active when gauge is hit even if the device leaves the collider. + if (isEffective && ctrl.isGaugeHit) return true; + + // Device movement is too slow to start activity. + if (!isEffective && deviceSpeed < 0.25f) return false; + + Collider[] colliders = Physics.OverlapCapsule(capsuleStart.position, capsuleEnd.position, radius); + foreach (var collider in colliders) + { + if (INTERACTING_COLLIDER_NAME_MATCHER.IsMatch(collider.name)) return true; + } + return false; + } + } +} From 3dd8bb1a9082337d940183d7fcc28fd3dec65fc5 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 1 Jan 2024 04:00:32 +0000 Subject: [PATCH 045/252] Create RadialMenu.cs --- BetterVR/RadialMenu.cs | 167 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 BetterVR/RadialMenu.cs diff --git a/BetterVR/RadialMenu.cs b/BetterVR/RadialMenu.cs new file mode 100644 index 0000000..64d8c6a --- /dev/null +++ b/BetterVR/RadialMenu.cs @@ -0,0 +1,167 @@ +using UnityEngine; +using UnityEngine.Rendering; +using System.Collections.Generic; +using TMPro; + +namespace BetterVR +{ + public class RadialMenu : MonoBehaviour + { + private const int ITEM_COUNT = 8; + private const float RADIUS = 1 / 16f; + private const float DEADZONE_RADIUS = 1 / 32f; + private const float ACTIVATION_DELAY_SECONDS = 0.33f; + + private GameObject cursor; + private TextMeshPro caption; + private List icons; + private LineRenderer lineRenderer; + private float activationTime; + + internal int selectedItemIndex { get; private set; } + internal Transform hand; + private string[] _captions; + internal string[] captions + { + private get { return _captions; } + set + { + _captions = value; + if (value == null) return; + for (int i = 0; i < _captions.Length; i++) + { + icons[i].text = _captions[i] == "" ? "-" : _captions[i].Substring(0, 1); + } + } + } + + void Awake() + { + CreateLines(); + CreateCursor(); + CreateCaption(); + } + + void OnEnable() + { + transform.parent = hand; + transform.localPosition = Vector3.zero; + transform.localRotation = Quaternion.Euler(90, 0, 0); + transform.localScale = Vector3.one; + transform.SetParent(BetterVRPluginHelper.VROrigin?.transform, worldPositionStays: true); + selectedItemIndex = -1; + activationTime = 0; + lineRenderer.enabled = false; + foreach (var icon in icons) icon.enabled = false; + } + + void Update() + { + transform.position += Vector3.Project(hand.position - transform.position, transform.forward); + + activationTime += Time.deltaTime; + + if (activationTime > ACTIVATION_DELAY_SECONDS) + { + lineRenderer.enabled = true; + foreach (var icon in icons) icon.enabled = true; + } + + Vector2 handProjection = transform.InverseTransformPoint(hand.position); + float handOffsetAmount = handProjection.magnitude; + if (handOffsetAmount < DEADZONE_RADIUS || activationTime < ACTIVATION_DELAY_SECONDS) + { + selectedItemIndex = -1; + cursor.transform.position = hand.position; + cursor.GetComponent().material.color = Color.gray; + caption.text = ""; + return; + } + + var angle = Vector2.SignedAngle(Vector2.right, handProjection); + int signedIndex = Mathf.RoundToInt(angle / 360 * ITEM_COUNT) % ITEM_COUNT; + selectedItemIndex = signedIndex >= 0 ? signedIndex : signedIndex + ITEM_COUNT; + + cursor.GetComponent().material.color = Color.yellow; + cursor.transform.localPosition = + GetCursorLocalDirection(selectedItemIndex) * Mathf.Clamp(handOffsetAmount, 0, RADIUS); + caption.text = GetCaption(selectedItemIndex); + } + + private Vector3 GetCursorLocalDirection(int itemIndex) + { + float angle = Mathf.PI * 2 * itemIndex / ITEM_COUNT; + return new Vector3(Mathf.Cos(angle), Mathf.Sin(angle)); + } + + private string GetCaption(int itemIndex) + { + if (itemIndex < 0 || captions == null || captions.Length <= itemIndex) return ""; + return captions[itemIndex]; + } + + private void CreateLines() + { + lineRenderer = gameObject.AddComponent(); + lineRenderer.useWorldSpace = false; + lineRenderer.positionCount = ITEM_COUNT * 2; + lineRenderer.widthMultiplier = 0.01f; + lineRenderer.material.color = Color.red; + + for (int i = 0; i < ITEM_COUNT; i++) + { + var cursorDirection = GetCursorLocalDirection(i); + lineRenderer.SetPosition(i * 2, Vector3.zero); + lineRenderer.SetPosition(i * 2 + 1, cursorDirection * RADIUS); + } + } + + private void CreateCursor() + { + cursor = GameObject.CreatePrimitive(PrimitiveType.Sphere); + cursor.transform.parent = transform; + cursor.transform.localScale = Vector3.one * RADIUS / 4; + var renderer = cursor.GetComponent(); + renderer.receiveShadows = false; + renderer.shadowCastingMode = ShadowCastingMode.Off; + renderer.lightProbeUsage = LightProbeUsage.Off; + renderer.reflectionProbeUsage = ReflectionProbeUsage.Off; + Destroy(cursor.GetComponent()); + } + + private void CreateCaption() + { + var captionCanvas = new GameObject("RadialMenuCaptionCanvas").AddComponent(); + captionCanvas.transform.SetParent(transform, worldPositionStays: false); + captionCanvas.transform.localScale = Vector3.one * 0.01f; + captionCanvas.GetComponent().sizeDelta = Vector3.one * 400 * RADIUS; + + var captionTransform = new GameObject("RadialMenuCaption").AddComponent(); + captionTransform.transform.SetParent(captionCanvas.transform, worldPositionStays: false); + captionTransform.localScale = Vector3.one; + captionTransform.anchorMin = captionTransform.anchorMax = new Vector2(0.5f, 0.875f); + captionTransform.offsetMin = new Vector2(-0.5f, -0.125f); + captionTransform.offsetMax = new Vector2(0.5f, 0.125f); + + caption = captionTransform.GetOrAddComponent(); + caption.alignment = TextAlignmentOptions.Center; + caption.fontSize = 16f; + caption.color = Color.yellow; + caption.m_width = captionTransform.sizeDelta.x; + + icons = new List(); + for (int i = 0; i < ITEM_COUNT; i++) + { + var iconTransform = new GameObject("RadialMenuIcon" + i).AddComponent(); + iconTransform.transform.SetParent(captionCanvas.transform, worldPositionStays: false); + iconTransform.transform.localScale = Vector3.one; + iconTransform.anchorMin = iconTransform.anchorMax = Vector3.one * 0.5f + GetCursorLocalDirection(i) * 0.3125f; + var icon = iconTransform.GetOrAddComponent(); + icon.alignment = TextAlignmentOptions.Center; + icon.fontSize = 12f; + icon.color = new Color(0.75f, 0.25f, 0); + icons.Add(icon); + } + } + } +} From fd7f452b5d66800f8abaf054a524d4f168e3e434 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 1 Jan 2024 04:01:35 +0000 Subject: [PATCH 046/252] Update VRController.Collider.cs --- BetterVR/VRController.Collider.cs | 89 +++++++++++++++++-------------- 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/BetterVR/VRController.Collider.cs b/BetterVR/VRController.Collider.cs index f2fbdaf..032728b 100644 --- a/BetterVR/VRController.Collider.cs +++ b/BetterVR/VRController.Collider.cs @@ -1,15 +1,16 @@ +using System.Text.RegularExpressions; using UnityEngine; namespace BetterVR { public static class VRControllerCollider { - private static readonly string[] INDEX_COLLIDING_BONE_PARTIAL_NAMES = new string[] { "agina", "okan" }; + private static readonly Regex INDEX_COLLIDING_BONE_MATCHER = new Regex(@"agina|okan"); + private static DynamicBoneCollider leftControllerCollider; + private static DynamicBoneCollider rightControllerCollider; + private static DynamicBoneCollider floorCollider; + private static DynamicBoneCollider mouthCollider; internal static Transform characterForHeightReference; - internal static DynamicBoneCollider leftControllerCollider; - internal static DynamicBoneCollider rightControllerCollider; - internal static DynamicBoneCollider floorCollider; - internal static DynamicBoneCollider mouthCollider; internal static void UpdateDynamicBoneColliders() { @@ -23,6 +24,7 @@ internal static void UpdateDynamicBoneColliders() UpdateControllerColliders(dynamicBones, dynamicBonesV2); UpdateIndexColliders(dynamicBones, dynamicBonesV2); + UpdateHandHeldToyCollider(dynamicBones, dynamicBonesV2); UpdateFloorCollider(dynamicBones, dynamicBonesV2); UpdateMouthCollider(dynamicBones, dynamicBonesV2); } @@ -33,7 +35,7 @@ private static void UpdateControllerColliders(DynamicBone[] dynamicBones, Dynami ref leftControllerCollider, "LeftControllerCollider", BetterVRPluginHelper.GetLeftHand(), - BetterVRPluginHelper.leftGlove?.GetComponent(), + BetterVRPluginHelper.leftGlove?.GetComponent(), -1, dynamicBones, dynamicBonesV2); @@ -41,7 +43,7 @@ private static void UpdateControllerColliders(DynamicBone[] dynamicBones, Dynami ref rightControllerCollider, "RightControllerCollider", BetterVRPluginHelper.GetRightHand(), - BetterVRPluginHelper.rightGlove?.GetComponent(), + BetterVRPluginHelper.rightGlove?.GetComponent(), 1, dynamicBones, dynamicBonesV2); @@ -49,7 +51,7 @@ private static void UpdateControllerColliders(DynamicBone[] dynamicBones, Dynami private static void UpdateControllerCollider( ref DynamicBoneCollider collider, string name, - GameObject controller, VRControllerInput.FingerPoseUpdater fingerPoses, float lateralFactor, + GameObject controller, FingerPoseUpdater fingerPoses, float lateralFactor, DynamicBone[] dynamicBones, DynamicBone_Ver02[] dynamicBonesV2) { var renderModel = BetterVRPluginHelper.FindControllerRenderModel(controller, out Vector3 center); @@ -63,16 +65,14 @@ private static void UpdateControllerCollider( collider.m_Radius = BetterVRPlugin.ControllerColliderRadius.Value; // A height too small will cause the collider to be ignored by some dynamic bones. - // Radius times 3 seems to be a good value for height. - collider.m_Height = BetterVRPlugin.ControllerColliderRadius.Value * 3; + collider.m_Height = BetterVRPlugin.ControllerColliderRadius.Value * 5; if (collider.transform.parent != renderModel) collider.transform.parent = renderModel; - if (fingerPoses && fingerPoses.middle && fingerPoses.ring) + if (fingerPoses?.middle) { collider.transform.position = - Vector3.Lerp(fingerPoses.middle.position, fingerPoses.ring.position, 0.5f) + - renderModel.TransformVector(Vector3.forward * 0.005f); + fingerPoses.middle.position + renderModel.TransformVector(Vector3.forward * 0.005f); } else { @@ -90,11 +90,19 @@ private static void UpdateMouthCollider(DynamicBone[] dynamicBones, DynamicBone_ { mouthCollider = new GameObject("MouthCollider").AddComponent(); mouthCollider.m_Direction = DynamicBoneColliderBase.Direction.Z; + Transform capsuleStart = new GameObject("MouthColliderCapsuleRear").transform; + Transform capsuleEnd = new GameObject("MouthColliderCapsuleFront").transform; + capsuleStart.parent = capsuleEnd.parent = mouthCollider.transform; + capsuleStart.localPosition = Vector3.back * 0.1f; + capsuleEnd.localPosition = Vector3.forward * 0.1f; + var h = mouthCollider.GetOrAddComponent(); + h.capsuleStart = capsuleStart; + h.capsuleEnd = capsuleEnd; + h.roleProperty = VRControllerInput.roleH; } mouthCollider.m_Radius = BetterVRPlugin.ControllerColliderRadius.Value; // A height too small will cause the collider to be ignored by some dynamic bones. - // Radius times 3 seems to be a good value for height. mouthCollider.m_Height = mouthCollider.m_Radius * 3; var camera = BetterVRPluginHelper.VRCamera; @@ -136,25 +144,33 @@ private static void UpdateFloorCollider(DynamicBone[] dynamicBones, DynamicBone_ private static void UpdateIndexColliders(DynamicBone[] dynamicBones, DynamicBone_Ver02[] dynamicBonesV2) { - var leftIndexCollider = BetterVRPluginHelper.leftGlove?.GetComponent()?.indexCollider; - if (leftIndexCollider) + if (VRGlove.isShowingGloves && BetterVRPluginHelper.leftGlove) { - AddColliderToDB(leftIndexCollider, dynamicBones, INDEX_COLLIDING_BONE_PARTIAL_NAMES); - AddColliderToDBv2(leftIndexCollider, dynamicBonesV2, INDEX_COLLIDING_BONE_PARTIAL_NAMES); + var leftIndexCollider = BetterVRPluginHelper.leftGlove.GetComponent()?.indexCollider; + AddColliderToDB(leftIndexCollider, dynamicBones, INDEX_COLLIDING_BONE_MATCHER); + AddColliderToDBv2(leftIndexCollider, dynamicBonesV2, INDEX_COLLIDING_BONE_MATCHER); } - var rightIndexCollider = BetterVRPluginHelper.rightGlove?.GetComponent()?.indexCollider; - if (rightIndexCollider) + if (VRGlove.isShowingGloves && BetterVRPluginHelper.rightGlove) { - AddColliderToDB(rightIndexCollider, dynamicBones, INDEX_COLLIDING_BONE_PARTIAL_NAMES); - AddColliderToDBv2(rightIndexCollider, dynamicBonesV2, INDEX_COLLIDING_BONE_PARTIAL_NAMES); + var rightIndexCollider = BetterVRPluginHelper.rightGlove.GetComponent()?.indexCollider; + AddColliderToDB(rightIndexCollider, dynamicBones, INDEX_COLLIDING_BONE_MATCHER); + AddColliderToDBv2(rightIndexCollider, dynamicBonesV2, INDEX_COLLIDING_BONE_MATCHER); } } + private static void UpdateHandHeldToyCollider(DynamicBone[] dynamicBones, DynamicBone_Ver02[] dynamicBonesV2) + { + var collider = BetterVRPluginHelper.handHeldToy?.collider; + if (!collider || !collider.isActiveAndEnabled) return; + AddColliderToDB(collider, dynamicBones); + AddColliderToDBv2(collider, dynamicBonesV2); + } + /// /// Links V2 dynamic bones to a controller collider /// - internal static void AddColliderToDBv2(DynamicBoneCollider collider, DynamicBone_Ver02[] dynamicBones, string[] partialNamesToMatch = null) + internal static void AddColliderToDBv2(DynamicBoneCollider collider, DynamicBone_Ver02[] dynamicBones, Regex boneNameMatcher = null) { if (collider == null) return; if (dynamicBones.Length == 0) return; @@ -165,11 +181,10 @@ internal static void AddColliderToDBv2(DynamicBoneCollider collider, DynamicBone for (int z = 0; z < dynamicBones.Length; z++) { //Check for existing interaction - if (!dynamicBones[z].Colliders.Contains(collider) && MatchesName(dynamicBones[z].name, partialNamesToMatch)) - { - dynamicBones[z].Colliders.Add(collider); - newDBCount++; - } + if (dynamicBones[z].Colliders.Contains(collider)) return; + if (boneNameMatcher != null && !boneNameMatcher.IsMatch(dynamicBones[z].name)) return; + dynamicBones[z].Colliders.Add(collider); + newDBCount++; } if (newDBCount > 0 && BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" Linked {newDBCount} new V2 colliders"); @@ -178,7 +193,7 @@ internal static void AddColliderToDBv2(DynamicBoneCollider collider, DynamicBone /// /// Links V1 dynamic bones to a controller collider /// - internal static void AddColliderToDB(DynamicBoneCollider collider, DynamicBone[] dynamicBones, string[] partialNamesToMatch = null) + internal static void AddColliderToDB(DynamicBoneCollider collider, DynamicBone[] dynamicBones, Regex boneNameMatcher = null) { if (collider == null) return; if (dynamicBones.Length == 0) return; @@ -189,21 +204,13 @@ internal static void AddColliderToDB(DynamicBoneCollider collider, DynamicBone[] for (int z = 0; z < dynamicBones.Length; z++) { //Check for existing interaction - if (!dynamicBones[z].m_Colliders.Contains(collider) && MatchesName(dynamicBones[z].name, partialNamesToMatch)) - { - dynamicBones[z].m_Colliders.Add(collider); - newDBCount++; - } + if (dynamicBones[z].m_Colliders.Contains(collider)) return; + if (boneNameMatcher != null && !boneNameMatcher.IsMatch(dynamicBones[z].name)) return; + dynamicBones[z].m_Colliders.Add(collider); + newDBCount++; } if (newDBCount > 0 && BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" Linked {newDBCount} new V1 colliders"); } - - private static bool MatchesName(string targetName, string[] partialNames) - { - if (partialNames == null) return true; - foreach (var partialName in partialNames) if (targetName.Contains(partialName)) return true; - return false; - } } } From c47c1971aadf60a994be53e9f493beb5408fd36e Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 1 Jan 2024 04:01:59 +0000 Subject: [PATCH 047/252] Update VRController.Hooks.cs --- BetterVR/VRController.Hooks.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/BetterVR/VRController.Hooks.cs b/BetterVR/VRController.Hooks.cs index b557049..75f3118 100644 --- a/BetterVR/VRController.Hooks.cs +++ b/BetterVR/VRController.Hooks.cs @@ -136,6 +136,13 @@ internal static void ChaControlLoadCharaFbxDataAsyncPrefix(AIChara.ChaControl __ } } + [HarmonyPostfix, HarmonyPatch(typeof(AIChara.ChaControl), "LoadCharaFbxDataAsync")] + internal static void ChaControlLoadCharaFbxDataAsyncPostfix(AIChara.ChaControl __instance) + { + BetterVRPluginHelper.UpdateControllersVisibilty(); + BetterVRPluginHelper.UpdatePrivacyScreen(Color.black); + } + [HarmonyPostfix, HarmonyPatch(typeof(Illusion.Component.UI.ColorPicker.Info), "SetImagePosition")] internal static void SetImagePositionReporter(Illusion.Component.UI.ColorPicker.Info __instance, PointerEventData cursorPos) { From aa6c1a9b69fdb835ab31ba31ce6428acb4784639 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 1 Jan 2024 04:02:39 +0000 Subject: [PATCH 048/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 194 ++++++--------------------------- 1 file changed, 35 insertions(+), 159 deletions(-) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index 7748ce0..731d823 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -1,16 +1,16 @@ -using BepInEx.Configuration; -using UnityEngine; +using TMPro; using HTC.UnityPlugin.Vive; -using IllusionUtility.GetUtility; +using System; +using UnityEngine; namespace BetterVR { public static class VRControllerInput { - - internal static ViveRoleProperty roleR = ViveRoleProperty.New(HandRole.RightHand); - internal static ViveRoleProperty roleL = ViveRoleProperty.New(HandRole.LeftHand); - private static bool isDraggingScale; + internal static ViveRoleProperty roleH { get; private set; } = ViveRoleProperty.New(DeviceRole.Hmd); + internal static ViveRoleProperty roleR { get; private set; } = ViveRoleProperty.New(HandRole.RightHand); + internal static ViveRoleProperty roleL { get; private set; } = ViveRoleProperty.New(HandRole.LeftHand); + internal static bool isDraggingScale { get; private set; } private static float scaleDraggingFactor; private static Vector3? leftHandPositionDuringGripMovement = null; private static Vector3? rightHandPositionDuringGripMovement = null; @@ -21,6 +21,16 @@ public static class VRControllerInput private static Vector3? lastVrOriginPosition; private static Quaternion? lastVrOriginRotation; + private static TextMeshPro _scaleIndicator; + private static TextMeshPro scaleIndicator + { + get + { + if (!_scaleIndicator || !_scaleIndicator.gameObject) _scaleIndicator = CreateScaleIndicator(); + return _scaleIndicator; + } + } + public static bool repositioningHand { get; private set; } = false; internal static void CheckInputForSqueezeScaling() @@ -31,6 +41,7 @@ internal static void CheckInputForSqueezeScaling() if (!shouldDragScale) { isDraggingScale = false; + scaleIndicator?.gameObject?.SetActive(false); if (BetterVRPluginHelper.LeftHandGripPress() && BetterVRPluginHelper.RightHandGripPress() && ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.AKey) @@ -47,68 +58,15 @@ internal static void CheckInputForSqueezeScaling() { // Start dragging scale isDraggingScale = true; + scaleIndicator?.gameObject?.SetActive(true); scaleDraggingFactor = handDistance * BetterVRPlugin.PlayerScale; return; } - BetterVRPlugin.PlayerScale = scaleDraggingFactor / handDistance; - } - - internal static void CheckInputForHandReposition() { - var leftHandOffset = BetterVRPlugin.LeftHandOffset; - var leftHandRotation = BetterVRPlugin.LeftHandRotation; - var rightHandOffset = BetterVRPlugin.RightHandOffset; - var rightHandRotation = BetterVRPlugin.RightHandRotation; - var leftHandRepositioning = - ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.AKey) && - ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.BKey) && - ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Trigger); - var rightHandRepositioning = - ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.AKey) && - ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.BKey) && - ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Trigger); - repositioningHand = leftHandRepositioning || rightHandRepositioning; - - if (BetterVRPluginHelper.leftGlove && BetterVRPluginHelper.leftGlove.activeInHierarchy) - { - UpdateHandTransform( - BetterVRPluginHelper.leftGlove.transform, - BetterVRPluginHelper.GetLeftHand(), - leftHandRepositioning, - ref leftHandOffset, - ref leftHandRotation); - } + float newScale = scaleDraggingFactor / handDistance; + scaleIndicator?.SetText("" + String.Format("{0:0.000}", newScale)); - if (BetterVRPluginHelper.rightGlove && BetterVRPluginHelper.rightGlove.activeInHierarchy) - { - UpdateHandTransform( - BetterVRPluginHelper.rightGlove.transform, - BetterVRPluginHelper.GetRightHand(), - rightHandRepositioning, - ref rightHandOffset, - ref rightHandRotation); - } - } - - private static void UpdateHandTransform( - Transform hand, GameObject controller, bool isRepositioning, - ref ConfigEntry offset, ref ConfigEntry localRotation) - { - if (hand == null) return; - - if (isRepositioning) - { - if (hand.parent != null) hand.SetParent(null, worldPositionStays: true); - } - else if (hand.parent == null) - { - var controllerRenderModel = BetterVRPluginHelper.FindControllerRenderModel(controller, out Vector3 center); - if (controllerRenderModel == null) return; - hand.SetParent(controllerRenderModel.parent); - localRotation.Value = hand.localRotation; - offset.Value = controllerRenderModel.InverseTransformVector(hand.position - center); - BetterVRPlugin.Logger.LogInfo("Set hand offset: " + hand.localRotation + " rotation: " + hand.localRotation.eulerAngles); - } + BetterVRPlugin.PlayerScale = newScale; } internal static void RecordVrOriginTransform() @@ -272,102 +230,20 @@ private static Vector3 GetAngularVelocityInRoomCoordinates(ViveRoleProperty hand return alternativeIsBetterFit ? alternativeCandidate : angularVelocity; } - internal class FingerPoseUpdater : MonoBehaviour + private static TextMeshPro CreateScaleIndicator() { - private HandRole handRole; - private float rotationFactor = 1; - private Transform thumb; - public Transform index { get; private set; } - public Transform middle { get; private set; } - public Transform ring { get; private set; } - private Transform pinky; - - public DynamicBoneCollider indexCollider { get; private set; } - - internal void Init(HandRole handRole, float rotationFactor = 1) - { - this.handRole = handRole; - this.rotationFactor = rotationFactor; - } - - void Awake() - { - thumb = FindFirstMatchingTransform(transform, "umb"); - index = FindFirstMatchingTransform(transform, "ndex"); - middle = FindFirstMatchingTransform(transform, "iddle"); - ring = FindFirstMatchingTransform(transform, "ing"); - pinky = FindFirstMatchingTransform(transform, "ittle"); - - if (index) { - indexCollider = new GameObject(name + "_indexCollider").AddComponent(); - indexCollider.m_Radius = 0.01f; - indexCollider.m_Height = 0.075f; - indexCollider.m_Direction = DynamicBoneColliderBase.Direction.X; - var colliderParent = index.childCount > 0 ? index.GetChild(0) : index; - if (colliderParent.childCount > 0) colliderParent = colliderParent.GetChild(0); - indexCollider.transform.parent = colliderParent; - indexCollider.transform.localPosition = Vector3.zero; - indexCollider.transform.localRotation = Quaternion.identity; - } - } - - void Update() - { - float thumbAngle = 35; - if (ViveInput.GetPressEx(handRole, ControllerButton.AKeyTouch) || - ViveInput.GetPressEx(handRole, ControllerButton.BkeyTouch) || - ViveInput.GetPressEx(handRole, ControllerButton.PadTouch) || - ViveInput.GetPressEx(handRole, ControllerButton.MenuTouch)) thumbAngle = 15; - if (thumb && thumb.childCount > 0) thumb.GetChild(0).localRotation = Quaternion.Euler(0, 0, thumbAngle * rotationFactor); - - float indexCurl = ViveInput.GetAxisEx(handRole, ControllerAxis.IndexCurl); - float middleCurl = ViveInput.GetAxisEx(handRole, ControllerAxis.MiddleCurl); - float ringCurl = ViveInput.GetAxisEx(handRole, ControllerAxis.RingCurl); - float pinkyCurl = ViveInput.GetAxisEx(handRole, ControllerAxis.PinkyCurl); - - if (indexCurl != 0 || middleCurl != 0 || ringCurl != 0 || pinkyCurl != 0) - { - UpdateAngle(index, indexCurl * 35); - UpdateAngle(middle, middleCurl * 60); - UpdateAngle(ring, ringCurl * 60); - UpdateAngle(pinky, pinkyCurl * 60); - return; - } - - float indexAngle = 10; - if (ViveInput.GetPressEx(handRole, ControllerButton.TriggerTouch)) indexAngle = 30; - indexAngle += ViveInput.GetAxisEx(handRole, ControllerAxis.Trigger) * 5; - - float gripAngle = 10; - if (ViveInput.GetPressEx(handRole, ControllerButton.TriggerTouch) || - ViveInput.GetPressEx(handRole, ControllerButton.GripTouch) || - ViveInput.GetPressEx(handRole, ControllerButton.CapSenseGripTouch)) gripAngle = 70; - gripAngle += ViveInput.GetAxisEx(handRole, ControllerAxis.CapSenseGrip) * 3; - - UpdateAngle(index, indexAngle); - UpdateAngle(middle, gripAngle); - UpdateAngle(ring, gripAngle * 1.15f); - UpdateAngle(pinky, gripAngle * 1.4f); - } - - private void UpdateAngle(Transform finger, float angle) - { - if (finger == null) return; - finger.localRotation = Quaternion.Euler(0, 0, angle * rotationFactor); - if (finger.childCount > 0) UpdateAngle(finger.GetChild(0), angle * 1.0625f); - } - - private static Transform FindFirstMatchingTransform(Transform transform, string partialName) - { - if (transform.name.Contains(partialName)) return transform; - - for (int i = 0; i < transform.childCount; i++) - { - Transform result = FindFirstMatchingTransform(transform.GetChild(i), partialName); - if (result) return result; - } - return null; - } + var camera = BetterVRPluginHelper.VRCamera; + if (!camera) return null; + var textMesh = + new GameObject().AddComponent().gameObject.AddComponent(); + textMesh.transform.SetParent(camera.transform); + textMesh.transform.localPosition = new Vector3 (0, 0.25f, 0.75f); + textMesh.transform.localRotation = Quaternion.identity; + textMesh.transform.localScale = Vector3.one * 0.1f; + textMesh.fontSize = 16; + textMesh.color = Color.blue; + textMesh.alignment = TextAlignmentOptions.Center; + return textMesh; } } } From 7773c39048e11697056439673446fe1a6a6a38ba Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 1 Jan 2024 04:03:35 +0000 Subject: [PATCH 049/252] Update VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 170 ++++++++++++++------------ 1 file changed, 89 insertions(+), 81 deletions(-) diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs index 4d3ff6e..7ca0091 100644 --- a/BetterVR/VrController.StripUpdater.cs +++ b/BetterVR/VrController.StripUpdater.cs @@ -1,16 +1,17 @@ using AIChara; +using System.Collections.Generic; +using System.Text.RegularExpressions; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; using HTC.UnityPlugin.Vive; -using System.Collections.Generic; namespace BetterVR { public class StripUpdater { - private const float STRIP_START_RANGE = 1f; + private const float STRIP_START_RANGE = 0.5f; private const float STRIP_MIN_DRAG_RANGE = 0.75f; private static readonly Color[] STRIP_INDICATOR_COLORS = new Color[] { Color.blue, Color.red, Color.cyan, Color.magenta, Color.yellow, Color.green, Color.white, Color.black }; @@ -30,12 +31,12 @@ internal StripUpdater(ViveRoleProperty handRole) internal void CheckStrip(bool enable) { - // LoadClothIcons(); + LoadClothIcons(); - Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; - if (vrOrigin == null) return; + if (BetterVRPluginHelper.VROrigin == null) return; - Vector3 handPos = vrOrigin.TransformPoint(VivePose.GetPose(handRole).pos); + Vector3 handPos = + BetterVRPluginHelper.VROrigin.transform.TransformPoint(VivePose.GetPose(handRole).pos); if (!enable || ViveInput.GetPress(handRole, ControllerButton.Grip)) // Disable stripping during possible movements @@ -57,9 +58,11 @@ internal void CheckStrip(bool enable) } canClothe = false; grabbedStripCollider = null; - stripIndicator.gameObject.SetActive(false); + stripIndicator?.gameObject.SetActive(false); + return; } - else if (ViveInput.GetPress(handRole, ControllerButton.Trigger)) + + if (ViveInput.GetPress(handRole, ControllerButton.Trigger)) { if (canClothe) { @@ -78,20 +81,17 @@ internal void CheckStrip(bool enable) } stripStartPos = handPos; } + return; } - else - { - grabbedStripCollider = FindClosestStripCollider(handPos, STRIP_START_RANGE * BetterVRPlugin.PlayerScale, 0, 1); - UpdateStripIndicator(); - stripStartPos = handPos; - canClothe = (grabbedStripCollider == null); - } + + grabbedStripCollider = FindClosestStripCollider(handPos, STRIP_START_RANGE * BetterVRPlugin.PlayerScale, 0, 1); + UpdateStripIndicator(); + stripStartPos = handPos; + canClothe = (grabbedStripCollider == null); } private void LoadClothIcons() { - // The icons are not actually working for some reason as for now. - if (finishedLoadingClothIcons || stripIndicator == null) { return; @@ -111,12 +111,10 @@ private void LoadClothIcons() if (!clothIconCanvas) { clothIconCanvas = new GameObject("ClothIconCanvas").AddComponent(); - clothIconCanvas.gameObject.AddComponent(); - clothIconCanvas.renderMode = RenderMode.ScreenSpaceOverlay; clothIconCanvas.transform.SetParent(stripIndicator.transform, false); clothIconCanvas.transform.localPosition = Vector3.zero; - clothIconCanvas.transform.localRotation = Quaternion.identity; - clothIconCanvas.transform.localScale = Vector3.one * 256f; + clothIconCanvas.transform.localRotation = Quaternion.Euler(120, 0, 0); + clothIconCanvas.transform.localScale = Vector3.one * 6; } bool waitingForIcons = false; @@ -127,14 +125,21 @@ private void LoadClothIcons() continue; } - var clothButtons = hSceneSprite.objCloth.objs; - if (clothButtons == null || clothButtons.Count <= i || clothButtons[i].buttons == null || clothButtons[i].buttons.Length == 0 || clothButtons[i].buttons[0] == null) + var allClothButtons = hSceneSprite.objCloth.objs; + if (allClothButtons == null || allClothButtons.Count <= i) + { + waitingForIcons = true; + continue; + } + var buttons = allClothButtons[i].buttons; + var buttonIndex = (i == 4 || i >= 6) ? 0 : 1; + if (buttons.Length <= buttonIndex) { waitingForIcons = true; continue; } - GameObject clothIcon = GameObject.Instantiate(clothButtons[i].buttons[0].gameObject); + GameObject clothIcon = GameObject.Instantiate(buttons[buttonIndex].gameObject); Object.Destroy(clothIcon.GetComponent internal static GameObject GetHand(VR_Hand hand) @@ -164,14 +158,14 @@ internal static GameObject GetHand(VR_Hand hand) internal static GameObject GetLeftHand() { var leftHand = GameObject.Find("ViveControllers/Left") ?? GameObject.Find("Controller (left)"); - if (leftHand && BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" GetLeftHand id {leftHand.GetInstanceID()}"); + // if (leftHand && BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" GetLeftHand id {leftHand.GetInstanceID()}"); return leftHand; } internal static GameObject GetRightHand() { var rightHand = GameObject.Find("ViveControllers/Right") ?? GameObject.Find("Controller (right)"); - if (rightHand && BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" GetRightHand id {rightHand.GetInstanceID()}"); + // if (rightHand && BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" GetRightHand id {rightHand.GetInstanceID()}"); return rightHand; } From 9057bb351cb01a1a29a3ee5f0db2342ed537f007 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 4 Jan 2024 18:24:09 +0000 Subject: [PATCH 112/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 284 +++++++++++++++++++++++++++++--------- 1 file changed, 219 insertions(+), 65 deletions(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index b4f7fcc..78fccf4 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -1,4 +1,5 @@ using HTC.UnityPlugin.Vive; +using System.Reflection; using System.Text.RegularExpressions; using UnityEngine; @@ -6,11 +7,9 @@ namespace BetterVR { public class HSpeedGesture : MonoBehaviour { - private const float LOOP_SLOW_FAST_DIVIDER = 1f; - private const float SLOW_MODE_ACTIVATION_THRESHOLD = 0.25f; - private const float FAST_MODE_ACTIVATION_THRESHOLD = 1.25f; private static readonly Regex SENSITIVE_COLLIDER_NAME_MATCHER = new Regex(@"[Mm]une|[Cc]hest|agina|okan"); private static readonly Regex MILD_COLLIDER_NAME_MATCHER = new Regex(@"[Nn]eck|[Ll]eg|[Ss]iri|[Bb]elly"); + private static readonly Regex SPNKABLE_COLLIDER_NAME_MATCHER = new Regex(@"[Ll]eg|[Ss]iri"); internal ViveRoleProperty roleProperty; internal Transform capsuleStart; @@ -20,9 +19,44 @@ public class HSpeedGesture : MonoBehaviour internal float sensitivityMultiplier = 1; internal Collider interactingCollider { get; private set; } - private float smoothTargetSpeed = 0; private bool isTouching; - private bool isColliderMild; + private bool isColliderSensitive; + private static HSpeedGestureReceiver receiver; + private static FinishHHaptic _leftHandHHaptic; + private static FinishHHaptic _rightHandHHaptic; + internal static FinishHHaptic leftHandHHaptic + { + get + { + if (_leftHandHHaptic == null) + { + _leftHandHHaptic = new GameObject("LeftHandHHaptic").AddComponent(); + _leftHandHHaptic.onLeftHand = true; + _leftHandHHaptic.onRightHand = false; + _leftHandHHaptic.enabled = false; + } + return _leftHandHHaptic; + } + } + internal static FinishHHaptic rightHandHHaptic + { + get + { + if (_rightHandHHaptic == null) + { + _rightHandHHaptic = new GameObject("RightHandHHaptic").AddComponent(); + _rightHandHHaptic.onLeftHand = false; + _rightHandHHaptic.onRightHand = true; + _rightHandHHaptic.enabled = false; + } + return _rightHandHHaptic; + } + } + + void Awake() + { + if (receiver == null) receiver = new GameObject("HSpeedGestureReceiver").AddComponent(); + } void FixedUpdate() { @@ -33,54 +67,42 @@ void FixedUpdate() float targetSpeed = VivePose.GetVelocity(roleProperty).magnitude * BetterVRPlugin.HandHSpeedSensitivity.Value * sensitivityMultiplier; isTouching = ShouldBeTouching(hCtrl, targetSpeed); - if (!isTouching && smoothTargetSpeed < 0.0625f) - { - smoothTargetSpeed = 0; - return; - } + if (!isTouching) return; - UpdateSmoothTargetSpeed(hCtrl, isTouching ? targetSpeed : 0); + UpdateSmoothTargetSpeed(targetSpeed, hCtrl); - if (isTouching && hCtrl.loopType >= 0 && hCtrl.loopType <= 2 && hCtrl.speed > 0 && BetterVRPlugin.HapticFeedbackIntensity.Value > 0) - { - ViveInput.TriggerHapticVibration( - roleProperty, frequency: hCtrl.isGaugeHit ? 60 : 35, - amplitude: smoothTargetSpeed / 4 * BetterVRPlugin.HapticFeedbackIntensity.Value); - } + var hScene = Singleton.Instance?.Hscene; + var anim = hScene?.GetProcBase(); - switch (hCtrl.loopType) + if (anim != null && anim is Spnking && interactingCollider != null && targetSpeed > 12 && + SPNKABLE_COLLIDER_NAME_MATCHER.IsMatch(interactingCollider.name) && + Spnk(hScene, hCtrl)) { - case -1: - smoothTargetSpeed = 0; - break; - case 0: - if (smoothTargetSpeed > FAST_MODE_ACTIVATION_THRESHOLD && !isColliderMild) - { - // Increase speed to move onto loop stage 1 - hCtrl.speed = FAST_MODE_ACTIVATION_THRESHOLD; - break; + BetterVRPlugin.Logger.LogDebug("Spnk speed: " + targetSpeed); + if (BetterVRPlugin.HapticFeedbackIntensity.Value > 0) + { + if (roleProperty == VRControllerInput.roleL) { + leftHandHHaptic.duration = 0.5f; + leftHandHHaptic.enabled = true; } - // Clamp speed to stay in loop stage 0. - hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, 0, LOOP_SLOW_FAST_DIVIDER - 0.0625f); - break; - case 1: - if (smoothTargetSpeed < SLOW_MODE_ACTIVATION_THRESHOLD) + else if (roleProperty == VRControllerInput.roleR) { - // Decrease speed to move back to loop stage 0 - hCtrl.speed = SLOW_MODE_ACTIVATION_THRESHOLD; - break; + rightHandHHaptic.duration = 0.5f; + rightHandHHaptic.enabled = true; } - // Clamp speed to stay in loop stage 1. - hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, LOOP_SLOW_FAST_DIVIDER + 0.0625f, 2f); - break; - default: - // Curve speed output to require faster movement. - hCtrl.speed = Mathf.Clamp(smoothTargetSpeed * smoothTargetSpeed / 2, 0, 2f); - if (hCtrl.isGaugeHit && hCtrl.feel_f > 0.99f && hCtrl.feel_m > 0.75f) BetterVRPluginHelper.TryFinishHSameTime(); - break; + } + } + else if (isTouching && targetSpeed > 0 && BetterVRPlugin.HapticFeedbackIntensity.Value > 0) + { + ViveInput.TriggerHapticVibration( + roleProperty, frequency: hCtrl.isGaugeHit ? 90 : 35, + amplitude: targetSpeed / 4 * BetterVRPlugin.HapticFeedbackIntensity.Value); } + } - BetterVRPluginHelper.gaugeHitIndicator.ShowIfGaugeIsHit(); + private bool Spnk(HScene hScene, HSceneFlagCtrl ctrl) + { + return hScene.GetProcBase()?.Proc(HSpeedGestureReceiver.GetModeCtrl(hScene), ctrl.nowAnimationInfo, 1) ?? false; } private bool ShouldBeTouching(HSceneFlagCtrl ctrl, float speed) @@ -93,61 +115,193 @@ private bool ShouldBeTouching(HSceneFlagCtrl ctrl, float speed) float scale = transform.lossyScale.x; - if (ctrl.loopType > 0 && isColliderMild) interactingCollider = null; - - if (interactingCollider) { + if (interactingCollider) + { Vector3 capsuleCenter = Vector3.Lerp(capsuleStart.position, capsuleEnd.position, 0.5f); if (Vector3.Distance(capsuleCenter, interactingCollider.ClosestPoint(capsuleCenter)) < deactivationDistance * scale) { + // Staying in the range of the current collider, can stay touching return true; } } interactingCollider = null; - bool canInteractWithMildCollider = ctrl.loopType < 1 && smoothTargetSpeed < 0.5f; + // bool canInteractWithMildCollider = smoothTargetSpeed < 0.5f; + + // Look for possible interacting colliders Collider[] colliders = Physics.OverlapCapsule(capsuleStart.position, capsuleEnd.position, activationRadius * scale); foreach (var collider in colliders) { + var stripCollider = collider.GetComponent(); + if (stripCollider == null || !stripCollider.IsCharacterVisible()) continue; + if (SENSITIVE_COLLIDER_NAME_MATCHER.IsMatch(collider.name)) { interactingCollider = collider; - isColliderMild = false; + isColliderSensitive = true; return true; } - if (canInteractWithMildCollider && MILD_COLLIDER_NAME_MATCHER.IsMatch(collider.name)) + + if (MILD_COLLIDER_NAME_MATCHER.IsMatch(collider.name)) { interactingCollider = collider; - isColliderMild = true; + isColliderSensitive = false; } } + return interactingCollider != null; } - private void UpdateSmoothTargetSpeed(HSceneFlagCtrl hCtrl, float targetSpeed) + private void UpdateSmoothTargetSpeed(float targetSpeed, HSceneFlagCtrl hCtrl) { - if (smoothTargetSpeed == targetSpeed) return; + if (!isTouching) return; + + // Do not let touching less sensitive parts affect speed during fast loop. + if (!isColliderSensitive && hCtrl.loopType > 0) return; + if (!isColliderSensitive && receiver.smoothTargetSpeed > 0.495f) return; + + // Do not start motion from idle state using hand gesture except in Aibu mode. + if (hCtrl.loopType == -1 && !HSpeedGestureReceiver.IsAibu()) return; + + targetSpeed = Mathf.Min(targetSpeed, hCtrl.loopType >= 0 ? 2f : 1f); + + if (targetSpeed <= receiver.smoothTargetSpeed) return; + + receiver.smoothTargetSpeed = Mathf.Clamp( + targetSpeed * Time.fixedDeltaTime * receiver.GetAccelerationFactor(hCtrl) + receiver.smoothTargetSpeed, + 0, targetSpeed); + } + } + + public class HSpeedGestureReceiver : MonoBehaviour + { + private const float IDLE_SPEED = -8f/64; + private const float MIN_EFFECTIVE_SPEED = -7f/64; + private const float LOOP_0_DEACTIVATION_THRESHOLD = -6f/64; + private const float LOOP_0_ACTIVATION_THRESHOLD = 0.625f; + private const float LOOP_01_DIVIDER = 1f; // This number is from the vanilla game + private const float LOOP_1_DEACTIVATION_THRESHOLD = 0.125f; + private const float LOOP_1_ACTIVATION_THRESHOLD = 1.5f; - targetSpeed = Mathf.Clamp(targetSpeed, 0, isColliderMild ? 0.5f : 2); + internal static bool shouldAttemptToStartAction { get; private set; } + private static FieldInfo modeCtrlField; - float accelerationFactor = 1f; - if (hCtrl.isGaugeHit) + internal float smoothTargetSpeed = 0; + private GaugeHitIndicator gaugeHitIndicator; + + void Awake() + { + modeCtrlField = typeof(HScene).GetField("modeCtrl", BindingFlags.NonPublic | BindingFlags.Instance); + } + + void FixedUpdate() + { + bool isEffective = (smoothTargetSpeed > MIN_EFFECTIVE_SPEED); + + (gaugeHitIndicator ?? (gaugeHitIndicator = new GaugeHitIndicator())).UpdateIndicators(isEffective); + + var hCtrl = Singleton.Instance; + if (!hCtrl) return; + + // Allow starting action using hand movement in Aibu mode. + shouldAttemptToStartAction = isEffective && IsAibu() && hCtrl.loopType == -1 && smoothTargetSpeed > LOOP_0_ACTIVATION_THRESHOLD; + + if (!isEffective) return; + + switch (hCtrl.loopType) { - // Damp the speed more to allow staying in gauge hit zone longer to avoid voice flickering. - accelerationFactor = 0.5f; + case -1: + break; + case 0: + if (IsAibu() && smoothTargetSpeed < LOOP_0_DEACTIVATION_THRESHOLD) + { + // Allow stopping action with hand motion in Aibu mode. + StopMotion(hCtrl); + hCtrl.speed = 0; + } + else if (smoothTargetSpeed > LOOP_1_ACTIVATION_THRESHOLD) + { + // Increase speed to move onto loop stage 1. + hCtrl.speed = LOOP_1_ACTIVATION_THRESHOLD; + } + else + { + // Clamp speed to stay in loop stage 0. + hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, 0, LOOP_01_DIVIDER - 0.01f); + } + break; + case 1: + if (smoothTargetSpeed < LOOP_1_DEACTIVATION_THRESHOLD) + { + // Decrease speed to move back to loop stage 0 + hCtrl.speed = LOOP_1_DEACTIVATION_THRESHOLD; + } + else + { + // Clamp speed to stay in loop stage 1. + hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, LOOP_01_DIVIDER + 0.01f, 2f); + } + break; + case 2: + // Curve speed output to require faster movement. + hCtrl.speed = Mathf.Clamp(smoothTargetSpeed * smoothTargetSpeed / 2, 0, 2f); + + if (hCtrl.isGaugeHit && hCtrl.feel_f > 0.99f && hCtrl.feel_m > 0.75f) BetterVRPluginHelper.TryFinishHSameTime(); + break; + case 3: + smoothTargetSpeed = 0; + break; } - smoothTargetSpeed = Mathf.Lerp(smoothTargetSpeed, targetSpeed, Time.fixedDeltaTime * accelerationFactor); + smoothTargetSpeed = Mathf.Lerp(smoothTargetSpeed, IDLE_SPEED, Time.fixedDeltaTime * GetAccelerationFactor(hCtrl)); // BetterVRPlugin.Logger.LogWarning( // "H Loop type: " + hCtrl.loopType + " current speed: " + hCtrl.speed + - // " smooth target speed: " + smoothTargetSpeed + " target speed: " + targetSpeed); + // " smooth target speed: " + smoothTargetSpeed); + } + + internal float GetAccelerationFactor(HSceneFlagCtrl ctrl) + { + // Damp the speed more when it is in gauge hit zone to avoid voice flickering. + if (ctrl.isGaugeHit && smoothTargetSpeed > 0.25f) return 0.25f / smoothTargetSpeed; + + // Damp the speed to delay starting Aibu. + if (ctrl.loopType == -1) return 0.375f; + + return smoothTargetSpeed <= 1 ? 1f : 1 / smoothTargetSpeed; + } + + internal static bool IsAibu() + { + var anim = Singleton.Instance?.Hscene?.GetProcBase(); + return anim != null && anim is Aibu; + } + + internal static int GetModeCtrl(HScene hScene) + { + return (int)(modeCtrlField.GetValue(hScene) ?? -1); + } + + private static void StartMotion(HSceneFlagCtrl ctrl) + { + HScene hScene = Singleton.Instance?.Hscene; + hScene?.GetProcBase()?.SetStartMotion(false, GetModeCtrl(hScene), ctrl.nowAnimationInfo); + } + + private static void StopMotion(HSceneFlagCtrl ctrl) + { + HScene hScene = Singleton.Instance?.Hscene; + hScene?.GetProcBase()?.SetStartMotion(true, GetModeCtrl(hScene), ctrl.nowAnimationInfo); } } internal class FinishHHaptic : MonoBehaviour { - const float DURATION = 3; + const float DEFAULT_DURATION = 3; private float timePassed = 0; + internal float duration = DEFAULT_DURATION; + internal bool onLeftHand = true; + internal bool onRightHand = true; void OnEnable() { @@ -156,16 +310,16 @@ void OnEnable() void FixedUpdate() { - if (timePassed > DURATION) + if (timePassed > duration) { enabled = false; return; } - var intensity = BetterVRPlugin.HapticFeedbackIntensity.Value * (1 - Mathf.Pow(timePassed / DURATION, 4f)); + var intensity = BetterVRPlugin.HapticFeedbackIntensity.Value * (1 - Mathf.Pow(timePassed / duration, 4f)); - ViveInput.TriggerHapticVibration(HandRole.LeftHand, amplitude: intensity); - ViveInput.TriggerHapticVibration(HandRole.RightHand, amplitude: intensity); + if (onLeftHand) ViveInput.TriggerHapticVibrationEx(HandRole.LeftHand, amplitude: intensity); + if (onRightHand) ViveInput.TriggerHapticVibrationEx(HandRole.RightHand, amplitude: intensity); timePassed += Time.fixedDeltaTime; } From 88cc3849b95f1c47cef799a365d5ad423bcce2cc Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 4 Jan 2024 18:24:43 +0000 Subject: [PATCH 113/252] Update VRController.Hooks.cs --- BetterVR/VRController.Hooks.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/BetterVR/VRController.Hooks.cs b/BetterVR/VRController.Hooks.cs index a697808..0bde26a 100644 --- a/BetterVR/VRController.Hooks.cs +++ b/BetterVR/VRController.Hooks.cs @@ -73,10 +73,9 @@ public static bool PatchGetAxis(HandRole _hand, ref Vector2 __result) // This method works for Oculus controllers' thumbsticks too. var axis = BetterVRPluginHelper.GetRightHandPadStickCombinedOutput(); - if (axis == Vector2.zero) - { - return true; - } + if (HSpeedGestureReceiver.shouldAttemptToStartAction) axis.y = 1; + + if (axis == Vector2.zero) return true; // The vanilla pad/thumb stick detection is half broken and does not work on some platforms, giving rise to the necessity of this patch. __result = axis; From 6e00e7b48d67044dcae9462ca8b5aa78971432a5 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 4 Jan 2024 18:44:07 +0000 Subject: [PATCH 114/252] Update VRController.Hooks.cs --- BetterVR/VRController.Hooks.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/VRController.Hooks.cs b/BetterVR/VRController.Hooks.cs index 0bde26a..3f59292 100644 --- a/BetterVR/VRController.Hooks.cs +++ b/BetterVR/VRController.Hooks.cs @@ -117,7 +117,7 @@ internal static void ChaControlLoadCharaFbxDataAsyncPostfix(AIChara.ChaControl _ [HarmonyPrefix, HarmonyPatch(typeof(HSceneSprite), nameof(HSceneSprite.OnClickFinishInSide))] internal static void HSceneFinishPatch() { - pluginInstance.GetOrAddComponent().enabled = true; + pluginInstance.GetOrAddComponent().enabled = true; } [HarmonyPrefix, HarmonyPatch(typeof(HSceneSprite), nameof(HSceneSprite.OnClickFinishOutSide))] From 141ba819bf4b7ce68ea6b622dce0ae7afd5ec6b1 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 4 Jan 2024 18:44:52 +0000 Subject: [PATCH 115/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 42 ++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index 78fccf4..cfa0281 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -22,15 +22,15 @@ public class HSpeedGesture : MonoBehaviour private bool isTouching; private bool isColliderSensitive; private static HSpeedGestureReceiver receiver; - private static FinishHHaptic _leftHandHHaptic; - private static FinishHHaptic _rightHandHHaptic; - internal static FinishHHaptic leftHandHHaptic + private static FadingHaptic _leftHandHHaptic; + private static FadingHaptic _rightHandHHaptic; + internal static FadingHaptic leftHandFadingHaptic { get { if (_leftHandHHaptic == null) { - _leftHandHHaptic = new GameObject("LeftHandHHaptic").AddComponent(); + _leftHandHHaptic = new GameObject("LeftHandHHaptic").AddComponent(); _leftHandHHaptic.onLeftHand = true; _leftHandHHaptic.onRightHand = false; _leftHandHHaptic.enabled = false; @@ -38,13 +38,13 @@ internal static FinishHHaptic leftHandHHaptic return _leftHandHHaptic; } } - internal static FinishHHaptic rightHandHHaptic + internal static FadingHaptic rightHandFadingHaptic { get { if (_rightHandHHaptic == null) { - _rightHandHHaptic = new GameObject("RightHandHHaptic").AddComponent(); + _rightHandHHaptic = new GameObject("RightHandHHaptic").AddComponent(); _rightHandHHaptic.onLeftHand = false; _rightHandHHaptic.onRightHand = true; _rightHandHHaptic.enabled = false; @@ -76,19 +76,19 @@ void FixedUpdate() if (anim != null && anim is Spnking && interactingCollider != null && targetSpeed > 12 && SPNKABLE_COLLIDER_NAME_MATCHER.IsMatch(interactingCollider.name) && - Spnk(hScene, hCtrl)) + receiver.Spnk(hScene, hCtrl)) { BetterVRPlugin.Logger.LogDebug("Spnk speed: " + targetSpeed); if (BetterVRPlugin.HapticFeedbackIntensity.Value > 0) { if (roleProperty == VRControllerInput.roleL) { - leftHandHHaptic.duration = 0.5f; - leftHandHHaptic.enabled = true; + leftHandFadingHaptic.duration = 0.25f; + leftHandFadingHaptic.enabled = true; } else if (roleProperty == VRControllerInput.roleR) { - rightHandHHaptic.duration = 0.5f; - rightHandHHaptic.enabled = true; + rightHandFadingHaptic.duration = 0.25f; + rightHandFadingHaptic.enabled = true; } } } @@ -100,11 +100,6 @@ void FixedUpdate() } } - private bool Spnk(HScene hScene, HSceneFlagCtrl ctrl) - { - return hScene.GetProcBase()?.Proc(HSpeedGestureReceiver.GetModeCtrl(hScene), ctrl.nowAnimationInfo, 1) ?? false; - } - private bool ShouldBeTouching(HSceneFlagCtrl ctrl, float speed) { // Movement is too slow to start activity. @@ -178,7 +173,7 @@ public class HSpeedGestureReceiver : MonoBehaviour private const float IDLE_SPEED = -8f/64; private const float MIN_EFFECTIVE_SPEED = -7f/64; private const float LOOP_0_DEACTIVATION_THRESHOLD = -6f/64; - private const float LOOP_0_ACTIVATION_THRESHOLD = 0.625f; + private const float LOOP_0_ACTIVATION_THRESHOLD = 0.5f; private const float LOOP_01_DIVIDER = 1f; // This number is from the vanilla game private const float LOOP_1_DEACTIVATION_THRESHOLD = 0.125f; private const float LOOP_1_ACTIVATION_THRESHOLD = 1.5f; @@ -277,15 +272,16 @@ internal static bool IsAibu() return anim != null && anim is Aibu; } - internal static int GetModeCtrl(HScene hScene) + internal bool Spnk(HScene hScene, HSceneFlagCtrl ctrl) { - return (int)(modeCtrlField.GetValue(hScene) ?? -1); + var anim = hScene.GetProcBase(); + if (anim == null || !(anim is Spnking)) return false; + return anim.Proc(GetModeCtrl(hScene), ctrl.nowAnimationInfo, 1); } - private static void StartMotion(HSceneFlagCtrl ctrl) + private static int GetModeCtrl(HScene hScene) { - HScene hScene = Singleton.Instance?.Hscene; - hScene?.GetProcBase()?.SetStartMotion(false, GetModeCtrl(hScene), ctrl.nowAnimationInfo); + return (int)(modeCtrlField.GetValue(hScene) ?? -1); } private static void StopMotion(HSceneFlagCtrl ctrl) @@ -295,7 +291,7 @@ private static void StopMotion(HSceneFlagCtrl ctrl) } } - internal class FinishHHaptic : MonoBehaviour + internal class FadingHaptic : MonoBehaviour { const float DEFAULT_DURATION = 3; private float timePassed = 0; From 0f0a54fc2a9f4815b7fec6106d40a92799efce31 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 4 Jan 2024 18:49:01 +0000 Subject: [PATCH 116/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index cfa0281..a8877a8 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -82,12 +82,12 @@ void FixedUpdate() if (BetterVRPlugin.HapticFeedbackIntensity.Value > 0) { if (roleProperty == VRControllerInput.roleL) { - leftHandFadingHaptic.duration = 0.25f; + leftHandFadingHaptic.duration = 0.375f; leftHandFadingHaptic.enabled = true; } else if (roleProperty == VRControllerInput.roleR) { - rightHandFadingHaptic.duration = 0.25f; + rightHandFadingHaptic.duration = 0.375f; rightHandFadingHaptic.enabled = true; } } From 666e49a69bbbd505eb2111bf7b521bd1ab0135b1 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 4 Jan 2024 19:02:12 +0000 Subject: [PATCH 117/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index 1b05290..8f96ed1 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -12,7 +12,7 @@ namespace BetterVR public partial class BetterVRPlugin : BaseUnityPlugin { public const string GUID = "BetterVR"; - public const string Version = "0.4"; + public const string Version = "0.45"; internal static new ManualLogSource Logger { get; private set; } #if DEBUG From 43dde2c1501407881f688705550c7467ac305472 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 4 Jan 2024 19:05:49 +0000 Subject: [PATCH 118/252] Update release.cmd --- release.cmd | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/release.cmd b/release.cmd index 5f638cf..282112a 100644 --- a/release.cmd +++ b/release.cmd @@ -1,9 +1,12 @@ ::Zips the dll into the correct directory structure for release ::Make sure to increment the version -set version=0.2 +set version=0.45 set name=HS2_BetterVR -IF EXIST "./bin/%name%/BepinEx/plugins/%name%.dll" "%ProgramFiles%\7-Zip\7z.exe" a -tzip "%HOMEPATH%/downloads/%name% v%version%.zip" "./bin/%name%/BepinEx" -mx0 +IF NOT EXIST "../release/%name%/BepInEx/plugins" MKDIR "../release/%name%/BepInEx/plugins" +COPY "../bin/%name%/BepinEx/plugins\%name%.dll" "../release/%name%/BepInEx/plugins" + +"%ProgramFiles%\7-Zip\7z.exe" a -tzip "%HOMEPATH%/downloads/%name% v%version%.zip" "../release/%name%" -mx0 +start %HOMEPATH%/downloads -start %HOMEPATH%/downloads \ No newline at end of file From b7bba1126fee09b3e4f55eb5817b926a3ebee7a9 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 06:50:32 +0000 Subject: [PATCH 119/252] Update VRGlove.cs --- BetterVR/VRGlove.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/VRGlove.cs b/BetterVR/VRGlove.cs index e0fc0fb..d9a10f6 100644 --- a/BetterVR/VRGlove.cs +++ b/BetterVR/VRGlove.cs @@ -78,7 +78,7 @@ void Update() ViveInput.GetPressDownEx(HandRole.RightHand, ControllerButton.AKey)) { isRepositioning = false; - transform.SetParent(controllerModel.parent); + transform.SetParent(controllerModel.parent, worldPositionStays: true); var offset = controllerModel.InverseTransformVector(transform.position - center); if (handRole == HandRole.LeftHand) { From 318c52945b08a8fe065148a5e1a76d20a5a72e02 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 06:51:33 +0000 Subject: [PATCH 120/252] Update HandHeldToy.cs --- BetterVR/HandHeldToy.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/BetterVR/HandHeldToy.cs b/BetterVR/HandHeldToy.cs index 5d4026c..a78947e 100644 --- a/BetterVR/HandHeldToy.cs +++ b/BetterVR/HandHeldToy.cs @@ -13,7 +13,6 @@ public class HandHeldToy : MonoBehaviour private static Transform bodyAttach; private Vector3 bodyAttachAngularVelocity; - private Vector3 bodyAttachVelocity; private int mode = 0; private GameObject simpleModel; @@ -176,11 +175,11 @@ private void CorrectBodyAttach(bool smooth = false) if (smooth) { targetForward = Vector3.SmoothDamp(bodyAttach.forward, targetForward, ref bodyAttachAngularVelocity, 0.25f); - targetPosition = Vector3.SmoothDamp(bodyAttach.position, targetPosition, ref bodyAttachVelocity, 0.0625f); + targetPosition = Vector3.Lerp(bodyAttach.position, targetPosition, Time.deltaTime * 32); } else { - bodyAttachVelocity = bodyAttachAngularVelocity = Vector3.zero; + bodyAttachAngularVelocity = Vector3.zero; } bodyAttach.SetPositionAndRotation(targetPosition, Quaternion.LookRotation(targetForward, bodyAttach.parent.up)); From ac5869249f6aec4f334cd2664f3c879e6117fece Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 06:52:09 +0000 Subject: [PATCH 121/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index 8f96ed1..4c397f8 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -12,7 +12,7 @@ namespace BetterVR public partial class BetterVRPlugin : BaseUnityPlugin { public const string GUID = "BetterVR"; - public const string Version = "0.45"; + public const string Version = "0.46"; internal static new ManualLogSource Logger { get; private set; } #if DEBUG @@ -104,10 +104,11 @@ private static void CheckRadialMenu(RadialMenu radialMenu, HandRole handRole) if (!radialMenu.isActiveAndEnabled) return; int selectedItemIndex = radialMenu.selectedItemIndex; - bool isTriggerDown = ViveInput.GetPressDownEx(handRole, ControllerButton.Trigger); + // bool isTriggerDown = ViveInput.GetPressDownEx(handRole, ControllerButton.Trigger); + bool isTriggerUp = ViveInput.GetPressUpEx(handRole, ControllerButton.Trigger); if (!menuShouldBeActive) radialMenu.gameObject.SetActive(false); - if (menuShouldBeActive && !isTriggerDown) return; + if (menuShouldBeActive && !isTriggerUp) return; switch (selectedItemIndex) { @@ -123,19 +124,17 @@ private static void CheckRadialMenu(RadialMenu radialMenu, HandRole handRole) BetterVRPluginHelper.FinishH(); break; case 3: - if (isTriggerDown) VRControllerInput.ResetWorldScale(); + if (isTriggerUp) VRControllerInput.ResetWorldScale(); break; case 4: BetterVRPluginHelper.CyclePlayerPDisplayMode(); VRControllerCollider.UpdateDynamicBoneColliders(); break; case 5: - if (isTriggerDown) - { - BetterVRPluginHelper.ResetView(); - BetterVRPluginHelper.UpdateControllersVisibilty(); - VRControllerCollider.UpdateDynamicBoneColliders(); - } + if (!isTriggerUp) break; + BetterVRPluginHelper.ResetView(); + BetterVRPluginHelper.UpdateControllersVisibilty(); + VRControllerCollider.UpdateDynamicBoneColliders(); break; case 6: // Toggle player body visibility. @@ -144,6 +143,7 @@ private static void CheckRadialMenu(RadialMenu radialMenu, HandRole handRole) VRControllerCollider.UpdateDynamicBoneColliders(); break; case 7: + if (!isTriggerUp) break; if (handRole == HandRole.LeftHand) { BetterVRPluginHelper.rightGlove?.StartRepositioning(); } From 776788e74625b60963cdebeaeca76fac3e3440bc Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 06:52:33 +0000 Subject: [PATCH 122/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index ea83a7d..8cf2147 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -36,6 +36,13 @@ internal static float handDistanceLocal } } + internal static HandRole GetHandRole(ViveRoleProperty roleProperty) + { + if (roleProperty == roleL) return HandRole.LeftHand; + if (roleProperty == roleR) return HandRole.RightHand; + return HandRole.Invalid; + } + internal static void RecordVrOriginTransform() { Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; From 96322c0428cd7642b788b92d5122165872828518 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 06:53:14 +0000 Subject: [PATCH 123/252] Update VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 46 ++++++++++----------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs index c518984..e72c5dc 100644 --- a/BetterVR/VrController.StripUpdater.cs +++ b/BetterVR/VrController.StripUpdater.cs @@ -194,15 +194,8 @@ private void UpdateStripIndicator() return; } - byte clothType = grabbedStripCollider.clothType; - if (clothType < 0 || clothType > STRIP_INDICATOR_COLORS.Length) - { - stripIndicator.gameObject.SetActive(false); - return; - } - stripIndicator.gameObject.SetActive(true); - stripIndicator.material.color = STRIP_INDICATOR_COLORS[clothType]; + stripIndicator.material.color = STRIP_INDICATOR_COLORS[grabbedStripCollider.clothType]; if (clothIcons == null) finishedLoadingClothIcons = false; if (!finishedLoadingClothIcons) return; @@ -213,7 +206,7 @@ private void UpdateStripIndicator() finishedLoadingClothIcons = false; return; } - clothIcons[i].SetActive(i == clothType); + clothIcons[i].SetActive(i == grabbedStripCollider.clothType); } // if (BetterVRPluginHelper.VRCamera) clothIconCanvas.transform.LookAt(BetterVRPluginHelper.VRCamera.transform); } @@ -228,7 +221,7 @@ private static StripCollider FindClosestStripCollider(Vector3 position, float ra StripCollider stripCollider = collider.GetComponent(); if (stripCollider == null || !stripCollider.IsInteractable()) continue; if (stripCollider.stripLevel < minStripLevel || stripCollider.stripLevel > maxStripLevel) continue; - float distance = collider.transform.InverseTransformPoint(position).magnitude; + float distance = collider.transform.InverseTransformVector(position - collider.ClosestPoint(position)).magnitude; if (distance < closestDistance) { closestDistance = distance; @@ -241,16 +234,18 @@ private static StripCollider FindClosestStripCollider(Vector3 position, float ra internal struct ColliderAnatomy { - public ColliderAnatomy(byte clothType, Vector3? scale = null, Vector3? offset = null) + public ColliderAnatomy(byte clothType, Vector3? scale = null, Vector3? offset = null, float? radius = null) { this.clothType = clothType; this.scale = scale ?? Vector3.one; this.offset = offset ?? Vector3.zero; + this.radius = radius ?? 0.5f; } internal byte clothType; internal Vector3 scale; internal Vector3 offset; + internal float radius; } public class StripColliderRegistry : MonoBehaviour @@ -259,7 +254,8 @@ public class StripColliderRegistry : MonoBehaviour private static readonly Dictionary NAME_MATCHER_TO_ANATOMY = new Dictionary { { new Regex(@"Spine02$"), new ColliderAnatomy(0, scale: Vector3.one * 1.5f) }, // Top - { new Regex(@"Kosi01$|Siri_[LR]$"), new ColliderAnatomy(1, Vector3.one * 1.25f) }, // Bottom + { new Regex(@"Kosi01$"), new ColliderAnatomy(1, Vector3.one * 1.25f) }, // Bottom + { new Regex(@"Siri_[LR]$"), new ColliderAnatomy(1, Vector3.one * 1.25f, null, 0.75f) }, // Bottom { new Regex(@"Belly_Mid_High"), new ColliderAnatomy(1, new Vector3(1f, 0.75f, 0.5f)) }, // Bottom { new Regex(@"Mune_Nip01_[LR]$"), new ColliderAnatomy(2) }, // Top inner { new Regex(@"Kokan$|agina_root$"), new ColliderAnatomy(3) }, // Under @@ -329,20 +325,10 @@ private void AddColliderInChildren(Transform transform) { if (!key.IsMatch(transform.name) || transform.name.Contains(COLLIDER_SUFFIX)) continue; - var anatomy = NAME_MATCHER_TO_ANATOMY[key]; - GameObject colliderObject; - if (StripCollider.IsValidClothType(anatomy.clothType)) - { - var collider = StripCollider.Create(character, anatomy, transform, null); - colliders.Add(collider); - colliderObject = collider.gameObject; - BetterVRPlugin.Logger.LogDebug("Added strip collider for " + transform.name + " on " + character.name); - } - else - { - colliderObject = StripCollider.CreateSphere(anatomy, transform, null); - } - colliderObject.name = transform.name + COLLIDER_SUFFIX; + var collider = StripCollider.Create(character, NAME_MATCHER_TO_ANATOMY[key], transform, null); + collider.name = transform.name + COLLIDER_SUFFIX; + colliders.Add(collider); + BetterVRPlugin.Logger.LogDebug("Added strip collider for " + transform.name + " on " + character.name); break; } @@ -352,7 +338,7 @@ private void AddColliderInChildren(Transform transform) public class StripCollider : MonoBehaviour { public byte clothType { get; private set; } - public byte stripLevel { get { return character.fileStatus.clothesState[clothType]; } } + public byte stripLevel { get { return IsValidClothType(clothType) ? character.fileStatus.clothesState[clothType] : (byte)0; } } private ChaControl character; internal static bool IsValidClothType(byte i) { return 0 <= i && i < 8; } @@ -375,7 +361,9 @@ internal static GameObject CreateSphere( sphere.transform.parent = parent; sphere.transform.localPosition = anatomy.offset; sphere.transform.localRotation = Quaternion.identity; - sphere.GetOrAddComponent().isTrigger = true; + var collider = sphere.GetOrAddComponent(); + collider.isTrigger = true; + collider.radius = anatomy.radius; var renderer = sphere.GetComponent(); if (shouldRender) { @@ -402,7 +390,7 @@ internal bool IsCharacterVisible() internal bool IsInteractable() { - return IsCharacterVisible() && character.IsClothes(clothType); + return IsCharacterVisible() && IsValidClothType(clothType) && character.IsClothes(clothType); } internal bool StripMore() From 6bdb4bc624160347ce6a0fc3753729006dd8d03d Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 06:53:55 +0000 Subject: [PATCH 124/252] Update VRMenu.Hooks.cs --- BetterVR/VRMenu.Hooks.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BetterVR/VRMenu.Hooks.cs b/BetterVR/VRMenu.Hooks.cs index bdfb4ed..c8f8875 100644 --- a/BetterVR/VRMenu.Hooks.cs +++ b/BetterVR/VRMenu.Hooks.cs @@ -125,7 +125,7 @@ internal static void PositionUnlockPatch(HSceneManager.HSceneTables __instance) { if (info == null || info.nStatePtns == null) continue; for (int i = 0; i < 7; i++) if (!info.nStatePtns.Contains(i)) info.nStatePtns.Add(i); - BetterVRPlugin.Logger.LogInfo("Unlocked position: " + info.nameAnimation); + // BetterVRPlugin.Logger.LogInfo("Unlocked position: " + info.nameAnimation); } } } @@ -148,7 +148,7 @@ internal static void SiriBoneRadiusFix(DynamicBone_Ver02 __instance) if (param.Name.Contains("Siri") || param.Name.Contains("siri")) { // Increase siri collision radius since the vanilla radius is too small for motion control interaction. - param.CollisionRadius = Mathf.Max(param.CollisionRadius, 0.75f); + param.CollisionRadius = Mathf.Max(param.CollisionRadius, 0.875f); } } } From 763548bd88c362345abcb690cecb6e526dc3396f Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 06:54:25 +0000 Subject: [PATCH 125/252] Update VRController.Hooks.cs --- BetterVR/VRController.Hooks.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/BetterVR/VRController.Hooks.cs b/BetterVR/VRController.Hooks.cs index 3f59292..49dc006 100644 --- a/BetterVR/VRController.Hooks.cs +++ b/BetterVR/VRController.Hooks.cs @@ -144,6 +144,12 @@ internal static void HSceneFinishPatchS() HSceneFinishPatch(); } + [HarmonyPostfix, HarmonyPatch(typeof(FeelHit), nameof(FeelHit.GetHitArea))] + internal static void FeelHitAreaRecorder(Vector2 __result) + { + HSpeedGesture.hitArea = __result; + } + [HarmonyPrefix, HarmonyPatch(typeof(Illusion.Component.UI.ColorPicker.Info), "SetImagePosition")] internal static void ColorPickerFix(Illusion.Component.UI.ColorPicker.Info __instance, PointerEventData cursorPos) { From 41dad0fb17be67a3c9bc6a235f0bc1ebb1b64a02 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 06:54:47 +0000 Subject: [PATCH 126/252] Update BetterVRPlugin.Config.cs --- BetterVR/GUI/BetterVRPlugin.Config.cs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/BetterVR/GUI/BetterVRPlugin.Config.cs b/BetterVR/GUI/BetterVRPlugin.Config.cs index ba4e480..9571ccb 100644 --- a/BetterVR/GUI/BetterVRPlugin.Config.cs +++ b/BetterVR/GUI/BetterVRPlugin.Config.cs @@ -1,5 +1,5 @@ using BepInEx.Configuration; -using HarmonyLib; +using System.Collections.Generic; using UnityEngine; namespace BetterVR @@ -9,6 +9,8 @@ public partial class BetterVRPlugin public static ConfigEntry EnableControllerColliders { get; private set; } public static ConfigEntry ControllerColliderRadius { get; private set; } public static ConfigEntry GestureStrip { get; private set; } + + public static ConfigEntry HandHSpeedGesture { get; private set; } public static ConfigEntry HandHSpeedSensitivity { get; private set; } public static ConfigEntry HapticFeedbackIntensity { get; private set; } @@ -54,10 +56,16 @@ public void PluginConfigInit() "Enable holding trigger and dragging away to undress or holding trigger and dragging onto to dress", new AcceptableValueList(new string[] { "Disabled", "Left hand", "Right hand" }))); + HandHSpeedGesture = Config.Bind( + "VR General", "Hand H Speed Gesture", "Auto", + new ConfigDescription( + "Enable controlling H action speed using hand motion", + new AcceptableValueList(new string[] { "Disabled", "Button-initiated", "Auto" }))); + HandHSpeedSensitivity = Config.Bind( "VR General", "Hand H Speed Sensitivty", 3, new ConfigDescription( - "Speed sensitivy when using hand movement to control H speed when touching certain parts, set to zero to disable this feature", + "Speed sensitivy when using hand movement to control H speed when touching certain parts", new AcceptableValueRange(0f, 8f))); HapticFeedbackIntensity = Config.Bind( @@ -154,6 +162,16 @@ internal static bool IsOneHandedTurnEnabled() return SqueezeToTurn.Value == "One-handed"; } + internal static bool IsHandHSpeedGestureEnabled() + { + return HandHSpeedGesture.Value != "Disabled"; + } + + internal static bool HandHSpeedGestureRequiresButtonPress() + { + return HandHSpeedGesture.Value == "Button-initiated"; + } + internal void FixWorldSizeScale_SettingsChanged(object sender, System.EventArgs e) { BetterVRPluginHelper.FixWorldScale(FixWorldSizeScale.Value); From bd48a2e148b6523e834a78469eb0429bb70b3e74 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 06:55:23 +0000 Subject: [PATCH 127/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 106 ++++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 26 deletions(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index a8877a8..c1a5940 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -19,12 +19,14 @@ public class HSpeedGesture : MonoBehaviour internal float sensitivityMultiplier = 1; internal Collider interactingCollider { get; private set; } + internal static Vector2 hitArea; + private bool isTouching; private bool isColliderSensitive; private static HSpeedGestureReceiver receiver; private static FadingHaptic _leftHandHHaptic; private static FadingHaptic _rightHandHHaptic; - internal static FadingHaptic leftHandFadingHaptic + private static FadingHaptic leftHandFadingHaptic { get { @@ -38,7 +40,7 @@ internal static FadingHaptic leftHandFadingHaptic return _leftHandHHaptic; } } - internal static FadingHaptic rightHandFadingHaptic + private static FadingHaptic rightHandFadingHaptic { get { @@ -60,25 +62,25 @@ void Awake() void FixedUpdate() { - if (BetterVRPlugin.HandHSpeedSensitivity.Value == 0 || roleProperty == null) return; + if (!BetterVRPlugin.IsHandHSpeedGestureEnabled() || roleProperty == null) return; var hCtrl = Singleton.Instance; if (!hCtrl) return; - float targetSpeed = + float speed = VivePose.GetVelocity(roleProperty).magnitude * BetterVRPlugin.HandHSpeedSensitivity.Value * sensitivityMultiplier; - isTouching = ShouldBeTouching(hCtrl, targetSpeed); + isTouching = ShouldBeTouching(speed); if (!isTouching) return; - UpdateSmoothTargetSpeed(targetSpeed, hCtrl); + UpdateSmoothTargetSpeed(speed, hCtrl); var hScene = Singleton.Instance?.Hscene; var anim = hScene?.GetProcBase(); - if (anim != null && anim is Spnking && interactingCollider != null && targetSpeed > 12 && + if (anim != null && anim is Spnking && interactingCollider != null && speed > 12 && SPNKABLE_COLLIDER_NAME_MATCHER.IsMatch(interactingCollider.name) && receiver.Spnk(hScene, hCtrl)) { - BetterVRPlugin.Logger.LogDebug("Spnk speed: " + targetSpeed); + BetterVRPlugin.Logger.LogDebug("Spnk speed: " + speed); if (BetterVRPlugin.HapticFeedbackIntensity.Value > 0) { if (roleProperty == VRControllerInput.roleL) { @@ -92,19 +94,32 @@ void FixedUpdate() } } } - else if (isTouching && targetSpeed > 0 && BetterVRPlugin.HapticFeedbackIntensity.Value > 0) + else if (isTouching && speed > 0 && BetterVRPlugin.HapticFeedbackIntensity.Value > 0) { - ViveInput.TriggerHapticVibration( - roleProperty, frequency: hCtrl.isGaugeHit ? 90 : 35, - amplitude: targetSpeed / 4 * BetterVRPlugin.HapticFeedbackIntensity.Value); + var amplitude = speed / 4 * BetterVRPlugin.HapticFeedbackIntensity.Value; + var frequency = hCtrl.isGaugeHit ? 120 : 35; + if (roleProperty == VRControllerInput.roleH) + { + ViveInput.TriggerHapticVibration(VRControllerInput.roleL, frequency: frequency, amplitude: amplitude / 4); + ViveInput.TriggerHapticVibration(VRControllerInput.roleR, frequency: frequency, amplitude: amplitude / 4); + } + else + { + ViveInput.TriggerHapticVibration(roleProperty, frequency: frequency, amplitude: amplitude); + } } } - private bool ShouldBeTouching(HSceneFlagCtrl ctrl, float speed) + private bool ShouldBeTouching(float speed) { - // Movement is too slow to start activity. - if (!isTouching && speed < 0.5f) return false; + var handRole = VRControllerInput.GetHandRole(roleProperty); + bool triggerOrGrip = + ViveInput.GetPressEx(handRole, ControllerButton.Trigger) || + ViveInput.GetPressEx(handRole, ControllerButton.Grip); + // Movement is too slow to start activity. + if (!isTouching && speed < 0.5f && !triggerOrGrip) return false; + if (capsuleStart == null) capsuleStart = transform; if (capsuleEnd == null) capsuleEnd = transform; @@ -121,7 +136,12 @@ private bool ShouldBeTouching(HSceneFlagCtrl ctrl, float speed) } interactingCollider = null; - // bool canInteractWithMildCollider = smoothTargetSpeed < 0.5f; + + if (BetterVRPlugin.HandHSpeedGestureRequiresButtonPress() && + handRole != HandRole.Invalid && !triggerOrGrip) + { + return false; + } // Look for possible interacting colliders Collider[] colliders = Physics.OverlapCapsule(capsuleStart.position, capsuleEnd.position, activationRadius * scale); @@ -147,18 +167,34 @@ private bool ShouldBeTouching(HSceneFlagCtrl ctrl, float speed) return interactingCollider != null; } - private void UpdateSmoothTargetSpeed(float targetSpeed, HSceneFlagCtrl hCtrl) + private void UpdateSmoothTargetSpeed(float speedInput, HSceneFlagCtrl hCtrl) { if (!isTouching) return; - // Do not let touching less sensitive parts affect speed during fast loop. - if (!isColliderSensitive && hCtrl.loopType > 0) return; - if (!isColliderSensitive && receiver.smoothTargetSpeed > 0.495f) return; + if (!isColliderSensitive && !HSpeedGestureReceiver.IsHoushi()) { + if (hCtrl.loopType > 0) + { + if (hCtrl.isGaugeHit && speedInput > 0 && speedInput < 1.75f && hitArea != null) + { + // Reward mild collider touching is fast loops by stabilizing gauge hit. + if (Random.Range(0f, 1f) < Time.fixedDeltaTime * 8) receiver.smoothTargetSpeed = Mathf.Lerp(hitArea.x, hitArea.y, 0.5f); + } + return; + } + else if (receiver.smoothTargetSpeed > 0.495f) + { + // Do not let touching less sensitive parts affect speed during fast movement. + return; + } + } // Do not start motion from idle state using hand gesture except in Aibu mode. if (hCtrl.loopType == -1 && !HSpeedGestureReceiver.IsAibu()) return; - targetSpeed = Mathf.Min(targetSpeed, hCtrl.loopType >= 0 ? 2f : 1f); + var targetSpeed = Mathf.Clamp(speedInput - 0.125f, 0, 2f); + + // Curve speed output to require faster movement. + if (hCtrl.loopType == 2) targetSpeed *= (targetSpeed / 2); if (targetSpeed <= receiver.smoothTargetSpeed) return; @@ -203,6 +239,13 @@ void FixedUpdate() if (!isEffective) return; + smoothTargetSpeed = Mathf.Lerp(smoothTargetSpeed, IDLE_SPEED, Time.fixedDeltaTime * GetAccelerationFactor(hCtrl)); + + if (IsMstrb()) { + if (hCtrl.loopType >= 0) hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, 0, 2f); + return; + } + switch (hCtrl.loopType) { case -1: @@ -238,9 +281,7 @@ void FixedUpdate() } break; case 2: - // Curve speed output to require faster movement. - hCtrl.speed = Mathf.Clamp(smoothTargetSpeed * smoothTargetSpeed / 2, 0, 2f); - + hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, 0, 2f); if (hCtrl.isGaugeHit && hCtrl.feel_f > 0.99f && hCtrl.feel_m > 0.75f) BetterVRPluginHelper.TryFinishHSameTime(); break; case 3: @@ -248,7 +289,7 @@ void FixedUpdate() break; } - smoothTargetSpeed = Mathf.Lerp(smoothTargetSpeed, IDLE_SPEED, Time.fixedDeltaTime * GetAccelerationFactor(hCtrl)); + // smoothTargetSpeed = Mathf.Lerp(smoothTargetSpeed, IDLE_SPEED, Time.fixedDeltaTime * GetAccelerationFactor(hCtrl)); // BetterVRPlugin.Logger.LogWarning( // "H Loop type: " + hCtrl.loopType + " current speed: " + hCtrl.speed + @@ -258,7 +299,7 @@ void FixedUpdate() internal float GetAccelerationFactor(HSceneFlagCtrl ctrl) { // Damp the speed more when it is in gauge hit zone to avoid voice flickering. - if (ctrl.isGaugeHit && smoothTargetSpeed > 0.25f) return 0.25f / smoothTargetSpeed; + if (ctrl.isGaugeHit && smoothTargetSpeed > 0.125f) return 0.125f / smoothTargetSpeed; // Damp the speed to delay starting Aibu. if (ctrl.loopType == -1) return 0.375f; @@ -272,6 +313,19 @@ internal static bool IsAibu() return anim != null && anim is Aibu; } + internal static bool IsMstrb() + { + var anim = Singleton.Instance?.Hscene?.GetProcBase(); + return anim != null && anim is Masturbation; + } + + internal static bool IsHoushi() + { + var anim = Singleton.Instance?.Hscene?.GetProcBase(); + return anim != null && anim is Houshi; + } + + internal bool Spnk(HScene hScene, HSceneFlagCtrl ctrl) { var anim = hScene.GetProcBase(); From e203fdd877729df0fde4fd2e5b12da81c1db1b5e Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 06:55:46 +0000 Subject: [PATCH 128/252] Update release.cmd --- release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.cmd b/release.cmd index 282112a..7a14630 100644 --- a/release.cmd +++ b/release.cmd @@ -1,7 +1,7 @@ ::Zips the dll into the correct directory structure for release ::Make sure to increment the version -set version=0.45 +set version=0.46 set name=HS2_BetterVR IF NOT EXIST "../release/%name%/BepInEx/plugins" MKDIR "../release/%name%/BepInEx/plugins" From 4d44e85122f8ba9efae8da6f8e18061065551965 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 06:57:32 +0000 Subject: [PATCH 129/252] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83c89b6..87bdb1e 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Forked from thojmr/HS2_BetterVR, this plugin for `Honey Select 2 VR` fixes a han - Fixes the bug of vanilla game not detecting thumb stick input on some platforms. - Fixes the bug of vanilla game resets camera when changing animation even if the camera initialization option is toggled off. - Fixes the non-interactable silhouette palette in game settings. -- Fixes the bug that all animations are frozen after opening mod config dialog and closing game settings dialog sometimmes. +- Fixes the bug that all animations are frozen after opening mod config dialog and closing game settings dialog sometimes. ## How to install From b0128a00260d2ec044710fc3553b42d652e5ae94 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 18:07:10 +0000 Subject: [PATCH 130/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 132 ++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 76 deletions(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index c1a5940..553f40e 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -100,8 +100,15 @@ void FixedUpdate() var frequency = hCtrl.isGaugeHit ? 120 : 35; if (roleProperty == VRControllerInput.roleH) { - ViveInput.TriggerHapticVibration(VRControllerInput.roleL, frequency: frequency, amplitude: amplitude / 4); - ViveInput.TriggerHapticVibration(VRControllerInput.roleR, frequency: frequency, amplitude: amplitude / 4); + if (!(BetterVRPluginHelper.GetLeftHand()?.GetComponentInChildren()?.isTouching ?? false)) + { + ViveInput.TriggerHapticVibration(VRControllerInput.roleL, frequency: frequency, amplitude: amplitude / 4); + } + if (!(BetterVRPluginHelper.GetRightHand()?.GetComponentInChildren()?.isTouching ?? false)) + { + ViveInput.TriggerHapticVibration(VRControllerInput.roleR, frequency: frequency, amplitude: amplitude / 4); + } + } else { @@ -177,20 +184,17 @@ private void UpdateSmoothTargetSpeed(float speedInput, HSceneFlagCtrl hCtrl) if (hCtrl.isGaugeHit && speedInput > 0 && speedInput < 1.75f && hitArea != null) { // Reward mild collider touching is fast loops by stabilizing gauge hit. - if (Random.Range(0f, 1f) < Time.fixedDeltaTime * 8) receiver.smoothTargetSpeed = Mathf.Lerp(hitArea.x, hitArea.y, 0.5f); + if (Random.Range(0f, 1f) < Time.fixedDeltaTime * 4) receiver.smoothTargetSpeed = Mathf.Lerp(hitArea.x, hitArea.y, 0.5f); } return; } - else if (receiver.smoothTargetSpeed > 0.495f) + else if (receiver.smoothTargetSpeed > HSpeedGestureReceiver.LOOP_01_DIVIDER - hCtrl.wheelActionCount) { // Do not let touching less sensitive parts affect speed during fast movement. return; } } - // Do not start motion from idle state using hand gesture except in Aibu mode. - if (hCtrl.loopType == -1 && !HSpeedGestureReceiver.IsAibu()) return; - var targetSpeed = Mathf.Clamp(speedInput - 0.125f, 0, 2f); // Curve speed output to require faster movement. @@ -206,15 +210,15 @@ private void UpdateSmoothTargetSpeed(float speedInput, HSceneFlagCtrl hCtrl) public class HSpeedGestureReceiver : MonoBehaviour { - private const float IDLE_SPEED = -8f/64; - private const float MIN_EFFECTIVE_SPEED = -7f/64; - private const float LOOP_0_DEACTIVATION_THRESHOLD = -6f/64; - private const float LOOP_0_ACTIVATION_THRESHOLD = 0.5f; - private const float LOOP_01_DIVIDER = 1f; // This number is from the vanilla game - private const float LOOP_1_DEACTIVATION_THRESHOLD = 0.125f; - private const float LOOP_1_ACTIVATION_THRESHOLD = 1.5f; - - internal static bool shouldAttemptToStartAction { get; private set; } + internal const float IDLE_SPEED = -8f/64; + internal const float MIN_EFFECTIVE_SPEED = -7f/64; + internal const float LOOP_0_DEACTIVATION_THRESHOLD = -6f/64; + internal const float LOOP_0_ACTIVATION_THRESHOLD = 0.5f; + internal const float LOOP_01_DIVIDER = 1f; // This number is from the vanilla game + internal const float LOOP_1_DEACTIVATION_THRESHOLD = 0.125f; + internal const float LOOP_1_ACTIVATION_THRESHOLD = 1.5f; + + internal static float outputY { get; private set; } private static FieldInfo modeCtrlField; internal float smoothTargetSpeed = 0; @@ -228,72 +232,55 @@ void Awake() void FixedUpdate() { bool isEffective = (smoothTargetSpeed > MIN_EFFECTIVE_SPEED); - (gaugeHitIndicator ?? (gaugeHitIndicator = new GaugeHitIndicator())).UpdateIndicators(isEffective); var hCtrl = Singleton.Instance; - if (!hCtrl) return; + if (!isEffective || !hCtrl) + { + outputY = 0; + return; + } - // Allow starting action using hand movement in Aibu mode. - shouldAttemptToStartAction = isEffective && IsAibu() && hCtrl.loopType == -1 && smoothTargetSpeed > LOOP_0_ACTIVATION_THRESHOLD; + outputY = GetOutput(hCtrl); + smoothTargetSpeed = Mathf.Lerp(smoothTargetSpeed, IDLE_SPEED, Time.fixedDeltaTime * GetAccelerationFactor(hCtrl)); - if (!isEffective) return; + if (IsAibu() && smoothTargetSpeed < LOOP_0_DEACTIVATION_THRESHOLD && hCtrl.loopType >= 0 && hCtrl.loopType <= 2) + { + // Allow stopping action with hand motion in Aibu mode. + StopMotion(hCtrl); + } + + if (hCtrl.isGaugeHit && hCtrl.feel_f > 0.99f && hCtrl.feel_m > 0.75f) BetterVRPluginHelper.TryFinishHSameTime(); - smoothTargetSpeed = Mathf.Lerp(smoothTargetSpeed, IDLE_SPEED, Time.fixedDeltaTime * GetAccelerationFactor(hCtrl)); + // BetterVRPlugin.Logger.LogWarning( + // "H Loop type: " + hCtrl.loopType + " current speed: " + hCtrl.speed + + // " smooth target speed: " + smoothTargetSpeed); + } - if (IsMstrb()) { - if (hCtrl.loopType >= 0) hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, 0, 2f); - return; + internal float GetOutput(HSceneFlagCtrl hCtrl) + { + if (hCtrl.loopType == -1) + { + // Allow starting action using hand movement in Aibu mode. + if (IsAibu() && smoothTargetSpeed > LOOP_0_ACTIVATION_THRESHOLD) return 1; + return 0; } - switch (hCtrl.loopType) + float bufferRadius = hCtrl.wheelActionCount; + var clampedSpeed = smoothTargetSpeed; + if (hCtrl.speed < LOOP_01_DIVIDER) { - case -1: - break; - case 0: - if (IsAibu() && smoothTargetSpeed < LOOP_0_DEACTIVATION_THRESHOLD) - { - // Allow stopping action with hand motion in Aibu mode. - StopMotion(hCtrl); - hCtrl.speed = 0; - } - else if (smoothTargetSpeed > LOOP_1_ACTIVATION_THRESHOLD) - { - // Increase speed to move onto loop stage 1. - hCtrl.speed = LOOP_1_ACTIVATION_THRESHOLD; - } - else - { - // Clamp speed to stay in loop stage 0. - hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, 0, LOOP_01_DIVIDER - 0.01f); - } - break; - case 1: - if (smoothTargetSpeed < LOOP_1_DEACTIVATION_THRESHOLD) - { - // Decrease speed to move back to loop stage 0 - hCtrl.speed = LOOP_1_DEACTIVATION_THRESHOLD; - } - else - { - // Clamp speed to stay in loop stage 1. - hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, LOOP_01_DIVIDER + 0.01f, 2f); - } - break; - case 2: - hCtrl.speed = Mathf.Clamp(smoothTargetSpeed, 0, 2f); - if (hCtrl.isGaugeHit && hCtrl.feel_f > 0.99f && hCtrl.feel_m > 0.75f) BetterVRPluginHelper.TryFinishHSameTime(); - break; - case 3: - smoothTargetSpeed = 0; - break; + if (clampedSpeed < LOOP_1_ACTIVATION_THRESHOLD) clampedSpeed = Mathf.Min(clampedSpeed, LOOP_01_DIVIDER - bufferRadius); + } + else + { + if (clampedSpeed > LOOP_1_DEACTIVATION_THRESHOLD) clampedSpeed = Mathf.Max(clampedSpeed, LOOP_01_DIVIDER + bufferRadius); } - // smoothTargetSpeed = Mathf.Lerp(smoothTargetSpeed, IDLE_SPEED, Time.fixedDeltaTime * GetAccelerationFactor(hCtrl)); + if (clampedSpeed >= hCtrl.speed + bufferRadius) return 1; + if (clampedSpeed <= hCtrl.speed - bufferRadius) return -1; - // BetterVRPlugin.Logger.LogWarning( - // "H Loop type: " + hCtrl.loopType + " current speed: " + hCtrl.speed + - // " smooth target speed: " + smoothTargetSpeed); + return 0; } internal float GetAccelerationFactor(HSceneFlagCtrl ctrl) @@ -313,19 +300,12 @@ internal static bool IsAibu() return anim != null && anim is Aibu; } - internal static bool IsMstrb() - { - var anim = Singleton.Instance?.Hscene?.GetProcBase(); - return anim != null && anim is Masturbation; - } - internal static bool IsHoushi() { var anim = Singleton.Instance?.Hscene?.GetProcBase(); return anim != null && anim is Houshi; } - internal bool Spnk(HScene hScene, HSceneFlagCtrl ctrl) { var anim = hScene.GetProcBase(); From 146cb406b1f9b17966a2ef0e5f5a1269a056ef8f Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 18:07:39 +0000 Subject: [PATCH 131/252] Update VRController.Hooks.cs --- BetterVR/VRController.Hooks.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BetterVR/VRController.Hooks.cs b/BetterVR/VRController.Hooks.cs index 49dc006..49acd83 100644 --- a/BetterVR/VRController.Hooks.cs +++ b/BetterVR/VRController.Hooks.cs @@ -26,7 +26,7 @@ internal static void LaserPointer_SetLeftLaserPointerActive(ControllerManager __ if (!value) return; //If the pointer game object is active, then set the cursor angle - if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" LaserPointer L active, setting angle to {BetterVRPlugin.SetVRControllerPointerAngle.Value}"); + // if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" LaserPointer L active, setting angle to {BetterVRPlugin.SetVRControllerPointerAngle.Value}"); // Not working currently. // pluginInstance.StartCoroutine( @@ -41,7 +41,7 @@ internal static void LaserPointer_SetRightLaserPointerActive(ControllerManager _ if (!value) return; //If the pointer game object is active, then set the cursor angle - if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" LaserPointer R active, setting angle to {BetterVRPlugin.SetVRControllerPointerAngle.Value}"); + // if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" LaserPointer R active, setting angle to {BetterVRPlugin.SetVRControllerPointerAngle.Value}"); // Not working currently. // pluginInstance.StartCoroutine( @@ -73,7 +73,7 @@ public static bool PatchGetAxis(HandRole _hand, ref Vector2 __result) // This method works for Oculus controllers' thumbsticks too. var axis = BetterVRPluginHelper.GetRightHandPadStickCombinedOutput(); - if (HSpeedGestureReceiver.shouldAttemptToStartAction) axis.y = 1; + axis.y += HSpeedGestureReceiver.outputY; if (axis == Vector2.zero) return true; From 758058bee73846ac85940fb5e0edd952979088a0 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 18:08:17 +0000 Subject: [PATCH 132/252] Update BetterVRPlugin.Config.cs --- BetterVR/GUI/BetterVRPlugin.Config.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/BetterVR/GUI/BetterVRPlugin.Config.cs b/BetterVR/GUI/BetterVRPlugin.Config.cs index 9571ccb..57a863a 100644 --- a/BetterVR/GUI/BetterVRPlugin.Config.cs +++ b/BetterVR/GUI/BetterVRPlugin.Config.cs @@ -18,6 +18,7 @@ public partial class BetterVRPlugin public static ConfigEntry PlayerLogScale { get; private set; } public static ConfigEntry SqueezeToTurn { get; private set; } public static ConfigEntry AllowVerticalRotation { get; private set; } + public static ConfigEntry ToyMovesVerticallyWhenAttachedToBody { get; private set; } public static ConfigEntry FixWorldSizeScale { get; private set; } public static ConfigEntry MultipleRandomHeroine { get; private set; } public static ConfigEntry UsePrivacyScreen { get; private set; } @@ -81,6 +82,10 @@ public void PluginConfigInit() AllowVerticalRotation = Config.Bind( "VR General", "Allow Vertical Rotation", false, new ConfigDescription("Allows rotating the world vertically.")); + ToyMovesVerticallyWhenAttachedToBody = Config.Bind( + "VR General", "Toy Moves Vertically When Attached To Body", true, + new ConfigDescription("Unlocks toy vertical movement when it is attached to body.")); + PlayerLogScale = Config.Bind( "VR General", "Log2 of Player Scale", Mathf.Log(1.15f, 2f), new ConfigDescription( @@ -147,10 +152,10 @@ public void PluginConfigInit() } - // internal void SetVRControllerPointerAngle_SettingsChanged(object sender, System.EventArgs e) - // { - // VRControllerPointer.UpdateOneOrMoreCtrlPointers(SetVRControllerPointerAngle.Value); - // } + internal void SetVRControllerPointerAngle_SettingsChanged(object sender, System.EventArgs e) + { + VRControllerPointer.UpdateOneOrMoreCtrlPointers(SetVRControllerPointerAngle.Value); + } internal static bool IsTwoHandedTurnEnabled() { From 2649f91c1a993f4b6027a92bf857e92b1ae8358b Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 5 Jan 2024 18:08:39 +0000 Subject: [PATCH 133/252] Update HandHeldToy.cs --- BetterVR/HandHeldToy.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/BetterVR/HandHeldToy.cs b/BetterVR/HandHeldToy.cs index a78947e..1a2f326 100644 --- a/BetterVR/HandHeldToy.cs +++ b/BetterVR/HandHeldToy.cs @@ -169,9 +169,13 @@ private void CorrectBodyAttach(bool smooth = false) // Make body attach face forward horizontally. var targetForward = Vector3.ProjectOnPlane(camera.transform.forward, bodyAttach.up); - // Move body attach to the horizontal position of the camera. - var targetPosition = - bodyAttach.parent.position + Vector3.ProjectOnPlane(camera.transform.position - bodyAttach.parent.position, bodyAttach.parent.up); + var targetPosition = camera.transform.position; + + if (!BetterVRPlugin.ToyMovesVerticallyWhenAttachedToBody.Value) + { + targetPosition = + bodyAttach.parent.position + Vector3.ProjectOnPlane(targetPosition - bodyAttach.parent.position, bodyAttach.parent.up); + } if (smooth) { targetForward = Vector3.SmoothDamp(bodyAttach.forward, targetForward, ref bodyAttachAngularVelocity, 0.25f); From af1a1f9a60bde875f2fc029e3c86f0526ddf646c Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:10:23 +0000 Subject: [PATCH 134/252] Update BetterVRPlugin.Helper.cs --- BetterVR/BetterVRPlugin.Helper.cs | 139 ++++++++++++++++-------------- 1 file changed, 74 insertions(+), 65 deletions(-) diff --git a/BetterVR/BetterVRPlugin.Helper.cs b/BetterVR/BetterVRPlugin.Helper.cs index 90d2d39..6c99b8b 100644 --- a/BetterVR/BetterVRPlugin.Helper.cs +++ b/BetterVR/BetterVRPlugin.Helper.cs @@ -23,10 +23,10 @@ public enum VR_Hand public static GameObject VROrigin; public static UnityEvent recenterVR { set; private get; } - private static Camera _VRCamera; private static GameObject simplePClone; private static int pDisplayMode = 1; // 0: invisible, 1: full, 2: silhouette + private static Camera _VRCamera; public static Camera VRCamera { get @@ -67,23 +67,43 @@ internal static VRGlove rightGlove } } + private static Transform _leftControllerCenter; + private static Transform _rightControllerCenter; + internal static Transform leftControllerCenter + { + get + { + if (CreateTransformIfNotPresent(ref _leftControllerCenter, parent: FindLeftControllerRenderModel(out var center))) + { + _leftControllerCenter.name = "LeftControllerCenter"; + _leftControllerCenter.position = center; + } + return _leftControllerCenter; + } + } + internal static Transform rightControllerCenter + { + get + { + if (CreateTransformIfNotPresent(ref _rightControllerCenter, parent: FindRightControllerRenderModel(out var center))) + { + _rightControllerCenter.name = "RightControllerCenter"; + _rightControllerCenter.position = center; + } + return _rightControllerCenter; + } + } + private static Transform _leftCursorAttach; private static Transform _rightCursorAttach; internal static Transform leftCursorAttach { get { - if (!_leftCursorAttach) _leftCursorAttach = new GameObject("LeftCursorAttach").transform; - var controllerModel = FindLeftControllerRenderModel(out var center); - if (controllerModel) + if (CreateTransformIfNotPresent(ref _leftCursorAttach, parent: leftControllerCenter)) { - if (_leftCursorAttach.parent != controllerModel.parent) - { - _leftCursorAttach.parent = controllerModel.parent; - _leftCursorAttach.localScale = Vector3.one; - _leftCursorAttach.localRotation = Quaternion.identity; - } - _leftCursorAttach.position = center + controllerModel.TransformVector(Vector3.forward * 0.1f); + _leftCursorAttach.name = "LeftCursorAttach"; + _leftCursorAttach.localPosition = Vector3.forward * 0.1f; } return _leftCursorAttach; } @@ -92,17 +112,10 @@ internal static Transform rightCursorAttach { get { - if (!_rightCursorAttach) _rightCursorAttach = new GameObject("RightCursorAttach").transform; - var controllerModel = FindRightControllerRenderModel(out var center); - if (controllerModel) + if (CreateTransformIfNotPresent(ref _rightCursorAttach, parent: rightControllerCenter)) { - if (_rightCursorAttach.parent != controllerModel.parent) - { - _rightCursorAttach.parent = controllerModel.parent; - _rightCursorAttach.localScale = Vector3.one; - _rightCursorAttach.localRotation = Quaternion.identity; - } - _rightCursorAttach.position = center + controllerModel.TransformVector(Vector3.forward * 0.125f); + _rightCursorAttach.name = "RightCursorAttach"; + _rightCursorAttach.localPosition = Vector3.forward * 0.1f; } return _rightCursorAttach; } @@ -241,7 +254,7 @@ private static void UpdatePDisplay() if (!player || !player.loadEnd) return; bool shouldUseSimpleP = Manager.Config.HData.Son && pDisplayMode == 2; - bool shouldUseRegularP = Manager.Config.HData.Son && pDisplayMode == 1; + bool shouldUseFullP = Manager.Config.HData.Son && pDisplayMode == 1; var simpleBodyEtc = player.cmpSimpleBody?.targetEtc; GameObject simpleBody = simpleBodyEtc?.objBody; @@ -252,7 +265,6 @@ private static void UpdatePDisplay() GameObject.Destroy(simplePClone); simplePClone = null; } - } if (shouldUseSimpleP && simplePClone == null) @@ -287,10 +299,10 @@ private static void UpdatePDisplay() var regularBodyEtc = player.cmpBody?.targetEtc; if (regularBodyEtc != null) { - regularBodyEtc.objMNPB?.SetActive(shouldUseRegularP); - regularBodyEtc.objDanTop?.SetActive(shouldUseRegularP); - regularBodyEtc.objDanSao?.SetActive(shouldUseRegularP); - regularBodyEtc.objDanTama?.SetActive(shouldUseRegularP); + regularBodyEtc.objMNPB?.SetActive(shouldUseFullP); + regularBodyEtc.objDanTop?.SetActive(shouldUseFullP); + regularBodyEtc.objDanSao?.SetActive(shouldUseFullP); + regularBodyEtc.objDanTama?.SetActive(shouldUseFullP); } } @@ -319,26 +331,6 @@ internal static void TryInitializeGloves() if (!_rightGlove) _rightGlove = VRGlove.CreateRightGlove(); } - internal static bool LeftHandTriggerPress() - { - return ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Trigger); - } - - internal static bool LeftHandGripPress() - { - return ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip); - } - - internal static bool RightHandTriggerPress() - { - return ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Trigger); - } - - internal static bool RightHandGripPress() - { - return ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip); - } - internal static void UpdatePrivacyScreen(Color? color = null) { EnsurePrivacyScreen().gameObject.SetActive(BetterVRPlugin.UsePrivacyScreen.Value); @@ -353,47 +345,64 @@ internal static Vector2 GetRightHandPadStickCombinedOutput() return output; } - internal static Transform FindLeftControllerRenderModel(out Vector3 center) + internal static void UpdateControllersVisibilty() + { + UpdateControllerVisibilty(FindControllerRenderModel(GetLeftHand(), out var lCenter)); + UpdateControllerVisibilty(FindControllerRenderModel(GetRightHand(), out var rCenter)); + } + + private static bool CreateTransformIfNotPresent(ref Transform transform, Transform parent) + { + if (parent == null) + { + if (transform != null) GameObject.Destroy(transform.gameObject); + transform = null; + return false; + } + + if (transform != null && transform.parent == parent) return false; + + if (transform != null) GameObject.Destroy(transform.gameObject); + + transform = new GameObject().transform; + transform.parent = parent; + transform.localPosition = Vector3.zero; + transform.localRotation = Quaternion.identity; + transform.localScale = Vector3.one; + + return true; + } + + private static Transform FindLeftControllerRenderModel(out Vector3 center) { return FindControllerRenderModel(GetLeftHand(), out center); } - internal static Transform FindRightControllerRenderModel(out Vector3 center) + private static Transform FindRightControllerRenderModel(out Vector3 center) { return FindControllerRenderModel(GetRightHand(), out center); } - internal static Transform FindControllerRenderModel(GameObject hand, out Vector3 center) + private static Transform FindControllerRenderModel(GameObject controller, out Vector3 center) { center = Vector3.zero; - if (hand == null) return null; + if (controller == null) return null; - Transform renderModel = hand.transform.FindLoop("Model") ?? hand.transform.FindLoop("OpenVRRenderModel"); + Transform renderModel = controller.transform.FindLoop("Model") ?? controller.transform.FindLoop("OpenVRRenderModel"); if (!renderModel) return null; var meshFilter = renderModel.GetComponentInChildren(); center = - meshFilter ? meshFilter.transform.TransformPoint(meshFilter.mesh.bounds.center) : hand.transform.position; + meshFilter ? meshFilter.transform.TransformPoint(meshFilter.mesh.bounds.center) : controller.transform.position; return renderModel; } - internal static void UpdateControllersVisibilty() - { - UpdateControllerVisibilty(FindControllerRenderModel(GetLeftHand(), out var lCenter)); - UpdateControllerVisibilty(FindControllerRenderModel(GetRightHand(), out var rCenter)); - } - private static void UpdateControllerVisibilty(Transform renderModel) { if (!renderModel) return; - - bool shouldShowController = - !VRGlove.isShowingGloves || - BetterVRPlugin.HandDisplay.Value == "Controllers" || - BetterVRPlugin.HandDisplay.Value == "GlovesAndControllers"; - + bool shouldShowController = !VRGlove.isShowingGloves || !BetterVRPlugin.IsHidingControllersEnabled(); var renderers = renderModel.GetComponentsInChildren(); foreach (var renderer in renderers) renderer.enabled = shouldShowController; } From 65241ac73f5892f561d6680c8f935683745d2d9e Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:11:20 +0000 Subject: [PATCH 135/252] Update BetterVRPlugin.Config.cs --- BetterVR/GUI/BetterVRPlugin.Config.cs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/BetterVR/GUI/BetterVRPlugin.Config.cs b/BetterVR/GUI/BetterVRPlugin.Config.cs index 57a863a..3320b68 100644 --- a/BetterVR/GUI/BetterVRPlugin.Config.cs +++ b/BetterVR/GUI/BetterVRPlugin.Config.cs @@ -93,10 +93,9 @@ public void PluginConfigInit() new AcceptableValueRange(-4, 4))); PlayerLogScale.SettingChanged += FixWorldSizeScale_SettingsChanged; - // SetVRControllerPointerAngle = Config.Bind("VR General", "(Not working yet)Laser Pointer Angle", 0, - // new ConfigDescription("0 is the default angle, and negative is down.", - // new AcceptableValueRange(-90, 90))); - // SetVRControllerPointerAngle.SettingChanged += SetVRControllerPointerAngle_SettingsChanged; + SetVRControllerPointerAngle = Config.Bind("VR General", "Laser Pointer Angle", -5, + new ConfigDescription("0 is the default angle, and negative is down", + new AcceptableValueRange(-90, 90))); FixWorldSizeScale = Config.Bind("VR General", "Fix World Scale", true, new ConfigDescription("Everything appears larger in VR, so this will shrink the worldsize down to a more realistic size.")); @@ -152,11 +151,6 @@ public void PluginConfigInit() } - internal void SetVRControllerPointerAngle_SettingsChanged(object sender, System.EventArgs e) - { - VRControllerPointer.UpdateOneOrMoreCtrlPointers(SetVRControllerPointerAngle.Value); - } - internal static bool IsTwoHandedTurnEnabled() { return SqueezeToTurn.Value == "Two-handed"; @@ -177,6 +171,16 @@ internal static bool HandHSpeedGestureRequiresButtonPress() return HandHSpeedGesture.Value == "Button-initiated"; } + internal static bool GlovesEnabled() + { + return HandDisplay.Value == "Gloves" || HandDisplay.Value == "GlovesAndControllers"; + } + + internal static bool IsHidingControllersEnabled() + { + return HandDisplay.Value == "Gloves"; + } + internal void FixWorldSizeScale_SettingsChanged(object sender, System.EventArgs e) { BetterVRPluginHelper.FixWorldScale(FixWorldSizeScale.Value); From 773fde6a1c8526881d916a17679f4d72407d8d2b Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:11:49 +0000 Subject: [PATCH 136/252] Update VRController.Pointer.cs --- BetterVR/VRController.Pointer.cs | 121 ++++++++++++------------------- 1 file changed, 48 insertions(+), 73 deletions(-) diff --git a/BetterVR/VRController.Pointer.cs b/BetterVR/VRController.Pointer.cs index 0ef168f..df410e6 100644 --- a/BetterVR/VRController.Pointer.cs +++ b/BetterVR/VRController.Pointer.cs @@ -1,5 +1,6 @@ using UnityEngine; using System.Collections; +using System.Reflection; namespace BetterVR { @@ -9,98 +10,72 @@ public static class VRControllerPointer /// /// Sets the angle of the laser pointer after some time to let the game objects settle /// - public static IEnumerator SetAngleAfterTime(float userAngle, BetterVRPluginHelper.VR_Hand hand = BetterVRPluginHelper.VR_Hand.none) + public static IEnumerator SetLaserAngleWithDelay(BetterVRPluginHelper.VR_Hand hand) { yield return new WaitForSeconds(0.01f); - UpdateOneOrMoreCtrlPointers(userAngle, hand); + GetHandAndSetAngle(hand); } - /// - /// Determine whether to set both hand angles or just one + /// Sets the angle of the laser pointer on the VR controller to the users configured value /// - public static void UpdateOneOrMoreCtrlPointers(float userAngle, BetterVRPluginHelper.VR_Hand hand = BetterVRPluginHelper.VR_Hand.none) + private static void GetHandAndSetAngle(BetterVRPluginHelper.VR_Hand vrHand) { - if (hand == BetterVRPluginHelper.VR_Hand.none) - { - GetHandAndSetAngle(userAngle, BetterVRPluginHelper.VR_Hand.left); - GetHandAndSetAngle(userAngle, BetterVRPluginHelper.VR_Hand.right); - } - else - { - GetHandAndSetAngle(userAngle, hand); - } - } + var controller = BetterVRPluginHelper.GetHand(vrHand); + var controllerCenter = + vrHand == BetterVRPluginHelper.VR_Hand.left ? + BetterVRPluginHelper.leftControllerCenter : + BetterVRPluginHelper.rightControllerCenter; + if (controller == null || controllerCenter == null) return; + var raycaster = controller.GetComponentInChildren(); + if (raycaster == null) return; - /// - /// Sets the angle of the laser pointer on the VR controller to the users configured value - /// - public static void GetHandAndSetAngle(float userAngle, BetterVRPluginHelper.VR_Hand hand) - { - //Get the correct hand - var vrHand = BetterVRPluginHelper.GetHand(hand); + // BetterVRPluginHelper.GetRightHand()?.GetComponentInChildren(); + // if (raycaster.transform.parent?.parent != controllerModel) - //Get all children components - var laserPointerTf = vrHand.transform.Find("LaserPointer"); + var laserSync = raycaster.gameObject.GetComponent(); - //Find the component one named laser pointer - if (laserPointerTf == null) return; + // Already patched. + if (laserSync != null && laserSync.source != null && laserSync.source.parent == controllerCenter) return; - CalculateControllerPointerAngle(userAngle, laserPointerTf.gameObject, vrHand); - } + // Leave the unpatched state available as an option in case there is some problem with the patch. + if (BetterVRPlugin.SetVRControllerPointerAngle.Value == 0) return; + if (controller.transform.Find("LaserPointer") == null) return; - /// - /// Calculates the controller laser pointer angle for a single hand - /// - public static void CalculateControllerPointerAngle(float userAngle, GameObject laserPointerGO, GameObject hand) - { - //Subtract the desired angle from the current angle, to get the rotational difference - var rotateAmount = GetNewAngleDifference(userAngle, laserPointerGO.transform); - - //Get line renderer start position to rotate around - var lineRenderer = laserPointerGO.GetComponentInChildren(); - if (lineRenderer == null) return; + // LaserSync not only offsets the laser angle, but also reduces the lag of laser movement. + laserSync = raycaster.GetOrAddComponent(); + laserSync.source = new GameObject(raycaster.name + "_originalTransform").transform; - //Get the starting position - var lineRendererStartPos = laserPointerGO.transform.TransformPoint(lineRenderer.GetPosition(0)); + // Parent the laser sync to the controller model so that its position and rotation is in sync with the controller. + laserSync.source.parent = controllerCenter; + laserSync.source.SetPositionAndRotation(raycaster.transform.position, raycaster.transform.rotation); - if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" lineRenderer.StartPos {lineRendererStartPos} laserPointerGO {laserPointerGO.transform.position}"); - if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" line comp to start dist {Vector3.Distance(lineRendererStartPos, laserPointerGO.transform.position)}"); - - //Rotate from the current position to the desired position - SetControllerPointerAngle(rotateAmount, laserPointerGO, lineRendererStartPos); - - // if (BetterVRPlugin.debugLog) DebugTools.DrawSphereAndAttach(lineRenderer.transform, 0.02f, lineRenderer.transform.position + lineRendererStartPos); - } - - - /// - /// Set the laser pointer oject rotation - /// - public static void SetControllerPointerAngle(float rotateAmount, GameObject laserPointerGO, Vector3 lineRendererStartPos) - { - laserPointerGO.transform.RotateAround(lineRendererStartPos, laserPointerGO.transform.right, rotateAmount); - - // if (BetterVRPlugin.debugLog) DebugTools.DrawSphereAndAttach(laserPointerGO.transform, 0.02f); + BetterVRPlugin.Logger.LogInfo("Laser pointer rotation offset applied"); } + } - - - /// - /// Get the differnce in rotation to the new angle - /// - public static float GetNewAngleDifference(float userAngle, Transform laserPointerTf) + class LaserSync : MonoBehaviour + { + internal Transform source; + private float offsetAngle = 0; + private Quaternion rotationOffset = Quaternion.identity; + + void Update() { - //Get the current laser pointer angle (0 is default) - var eulers = laserPointerTf.rotation.eulerAngles; + if (source == null) return; - if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" LaserPointer current {eulers.x} new {userAngle}"); - - //Subtract the desired angle from the current angle, to get the rotational difference - return userAngle - eulers.x; + if (offsetAngle != BetterVRPlugin.SetVRControllerPointerAngle.Value) + { + offsetAngle = BetterVRPlugin.SetVRControllerPointerAngle.Value; + rotationOffset = Quaternion.Euler(-offsetAngle, 0, 0); + } + + // Move the object to the desired positon and rotation relative to the controller model. + // The vanilla laser pointer stabilization is too aggressive and causes a laggy feel. + // Updating the laser direction here also reduces soem of the lag. + transform.SetPositionAndRotation(source.position, source.rotation * rotationOffset); } - } -} \ No newline at end of file +} From 54d7ffee1fb4ceb85f069d47a810bd2656f789b3 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:12:11 +0000 Subject: [PATCH 137/252] Update VRController.Hooks.cs --- BetterVR/VRController.Hooks.cs | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/BetterVR/VRController.Hooks.cs b/BetterVR/VRController.Hooks.cs index 49acd83..5374007 100644 --- a/BetterVR/VRController.Hooks.cs +++ b/BetterVR/VRController.Hooks.cs @@ -24,35 +24,23 @@ public static void InitHooks(Harmony harmonyInstance, BetterVRPlugin _pluginInst internal static void LaserPointer_SetLeftLaserPointerActive(ControllerManager __instance, bool value) { if (!value) return; - - //If the pointer game object is active, then set the cursor angle - // if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" LaserPointer L active, setting angle to {BetterVRPlugin.SetVRControllerPointerAngle.Value}"); - - // Not working currently. - // pluginInstance.StartCoroutine( - // VRControllerPointer.SetAngleAfterTime(BetterVRPlugin.SetVRControllerPointerAngle.Value, BetterVRPluginHelper.VR_Hand.left) - // ); - + pluginInstance.StartCoroutine( + VRControllerPointer.SetLaserAngleWithDelay(BetterVRPluginHelper.VR_Hand.left)); } [HarmonyPostfix, HarmonyPatch(typeof(ControllerManager), nameof(ControllerManager.SetRightLaserPointerActive), typeof(bool))] internal static void LaserPointer_SetRightLaserPointerActive(ControllerManager __instance, bool value) { if (!value) return; - - //If the pointer game object is active, then set the cursor angle - // if (BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" LaserPointer R active, setting angle to {BetterVRPlugin.SetVRControllerPointerAngle.Value}"); - - // Not working currently. - // pluginInstance.StartCoroutine( - // VRControllerPointer.SetAngleAfterTime(BetterVRPlugin.SetVRControllerPointerAngle.Value, BetterVRPluginHelper.VR_Hand.right) - // ); + pluginInstance.StartCoroutine( + VRControllerPointer.SetLaserAngleWithDelay(BetterVRPluginHelper.VR_Hand.right)); } [HarmonyPrefix, HarmonyPatch(typeof(HS2VR.GripMoveCrtl), "ControllerMove")] internal static bool ControllerMovePatch() { - if (!BetterVRPluginHelper.LeftHandGripPress() && !BetterVRPluginHelper.RightHandGripPress()) + if (!ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip) && + !ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip)) { // If no grip is pressed, allow vanilla logic to handle turning. return true; From fea060eac10aabb8ba5853e300a5308130e7e99a Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:12:50 +0000 Subject: [PATCH 138/252] Update VRController.Collider.cs --- BetterVR/VRController.Collider.cs | 144 ++++++++++-------------------- 1 file changed, 47 insertions(+), 97 deletions(-) diff --git a/BetterVR/VRController.Collider.cs b/BetterVR/VRController.Collider.cs index 4806644..cde9466 100644 --- a/BetterVR/VRController.Collider.cs +++ b/BetterVR/VRController.Collider.cs @@ -19,52 +19,43 @@ internal static void UpdateDynamicBoneColliders() var females = Singleton.Instance?.Hscene?.GetFemales(); if (females == null || females.Length == 0) return; - DynamicBone_Ver02[] dynamicBonesV2 = { }; - DynamicBone[] dynamicBones = { }; - //Get all dynamic bones - for (int i = 0; i < females.Length; i++) + UpdateControllerColliders(); + UpdateIndexColliders(); + UpdateHandHeldToyCollider(); + UpdateFloorCollider(); + UpdateMouthCollider(); + + foreach (var character in females) { - if (females[i] == null) continue; - dynamicBonesV2 = dynamicBonesV2.Concat(females[i].GetComponentsInChildren()).ToArray(); - dynamicBones = dynamicBones.Concat(females[i].GetComponentsInChildren()).ToArray(); + if (character == null) continue; + var dynamicBones = character.GetComponentsInChildren(); + foreach (var bone in dynamicBones) AddCollidersToBone(bone); + var dynamicBonesV2 = character.GetComponentsInChildren(); + foreach (var bone in dynamicBonesV2) AddCollidersToBone(bone); } - - if (dynamicBonesV2.Length == 0 && dynamicBones.Length == 0) return; - - UpdateControllerColliders(dynamicBones, dynamicBonesV2); - UpdateIndexColliders(dynamicBones, dynamicBonesV2); - UpdateHandHeldToyCollider(dynamicBones, dynamicBonesV2); - UpdateFloorCollider(dynamicBones, dynamicBonesV2); - UpdateMouthCollider(dynamicBones, dynamicBonesV2); } - private static void UpdateControllerColliders(DynamicBone[] dynamicBones, DynamicBone_Ver02[] dynamicBonesV2) + private static void UpdateControllerColliders() { UpdateControllerCollider( ref leftControllerCollider, "LeftControllerCollider", - BetterVRPluginHelper.GetLeftHand(), + BetterVRPluginHelper.leftControllerCenter, BetterVRPluginHelper.leftGlove?.GetComponent(), - -1, - dynamicBones, - dynamicBonesV2); + -1); UpdateControllerCollider( ref rightControllerCollider, "RightControllerCollider", - BetterVRPluginHelper.GetRightHand(), + BetterVRPluginHelper.rightControllerCenter, BetterVRPluginHelper.rightGlove?.GetComponent(), - 1, - dynamicBones, - dynamicBonesV2); + 1); } private static void UpdateControllerCollider( ref DynamicBoneCollider collider, string name, - GameObject controller, FingerPoseUpdater fingerPoses, float lateralFactor, - DynamicBone[] dynamicBones, DynamicBone_Ver02[] dynamicBonesV2) + Transform controllerCenter, FingerPoseUpdater fingerPoses, float lateralFactor) { - var renderModel = BetterVRPluginHelper.FindControllerRenderModel(controller, out Vector3 center); - if (!renderModel) return; + if (!controllerCenter) return; if (!collider) { @@ -76,26 +67,22 @@ private static void UpdateControllerCollider( // A height too small will cause the collider to be ignored by some dynamic bones. collider.m_Height = BetterVRPlugin.ControllerColliderRadius.Value * 5; - if (collider.transform.parent != renderModel) collider.transform.parent = renderModel; + if (collider.transform.parent != controllerCenter) collider.transform.parent = controllerCenter; if (fingerPoses?.middle) { - collider.transform.position = - fingerPoses.middle.position + renderModel.TransformVector(Vector3.forward * 0.005f); + collider.transform.localPosition = + controllerCenter.InverseTransformPoint(fingerPoses.middle.position) + Vector3.forward * 0.005f; } else { - collider.transform.position = - center + renderModel.TransformVector(new Vector3(0.01f * lateralFactor, 0, 0.005f)); + collider.transform.localPosition = new Vector3(0.01f * lateralFactor, 0, 0.005f); } collider.enabled = BetterVRPlugin.EnableControllerColliders.Value; - - AddColliderToDB(collider, dynamicBones); - AddColliderToDBv2(collider, dynamicBonesV2); } - private static void UpdateMouthCollider(DynamicBone[] dynamicBones, DynamicBone_Ver02[] dynamicBonesV2) + private static void UpdateMouthCollider() { if (mouthCollider == null) { @@ -125,12 +112,9 @@ private static void UpdateMouthCollider(DynamicBone[] dynamicBones, DynamicBone_ mouthCollider.transform.localPosition = new Vector3(0, -0.08f, 0.03f); mouthCollider.enabled = BetterVRPlugin.EnableControllerColliders.Value; - - AddColliderToDB(mouthCollider, dynamicBones); - AddColliderToDBv2(mouthCollider, dynamicBonesV2); } - private static void UpdateFloorCollider(DynamicBone[] dynamicBones, DynamicBone_Ver02[] dynamicBonesV2) + private static void UpdateFloorCollider() { if (floorCollider == null) { @@ -151,90 +135,56 @@ private static void UpdateFloorCollider(DynamicBone[] dynamicBones, DynamicBone_ characterForHeightReference == null ? vrOrgin.position.y : characterForHeightReference.position.y, vrOrgin.position.z); } - - AddColliderToDB(floorCollider, dynamicBones); - AddColliderToDBv2(floorCollider, dynamicBonesV2); } - private static void UpdateIndexColliders(DynamicBone[] dynamicBones, DynamicBone_Ver02[] dynamicBonesV2) + private static void UpdateIndexColliders() { if (VRGlove.isShowingGloves && BetterVRPluginHelper.leftGlove) { var leftIndexCollider = BetterVRPluginHelper.leftGlove.GetComponent()?.indexCollider; if (leftIndexCollider) leftIndexCollider.enabled = BetterVRPlugin.EnableControllerColliders.Value; - AddColliderToDB(leftIndexCollider, dynamicBones, INDEX_COLLIDING_BONE_MATCHER); - AddColliderToDBv2(leftIndexCollider, dynamicBonesV2, INDEX_COLLIDING_BONE_MATCHER); } if (VRGlove.isShowingGloves && BetterVRPluginHelper.rightGlove) { var rightIndexCollider = BetterVRPluginHelper.rightGlove.GetComponent()?.indexCollider; if (rightIndexCollider) rightIndexCollider.enabled = BetterVRPlugin.EnableControllerColliders.Value; - AddColliderToDB(rightIndexCollider, dynamicBones, INDEX_COLLIDING_BONE_MATCHER); - AddColliderToDBv2(rightIndexCollider, dynamicBonesV2, INDEX_COLLIDING_BONE_MATCHER); } } - private static void UpdateHandHeldToyCollider(DynamicBone[] dynamicBones, DynamicBone_Ver02[] dynamicBonesV2) + private static void UpdateHandHeldToyCollider() { var collider = BetterVRPluginHelper.handHeldToy?.collider; - if (!collider || !collider.isActiveAndEnabled) return; - AddColliderToDB(collider, dynamicBones); - AddColliderToDBv2(collider, dynamicBonesV2); + if (collider) collider.enabled = BetterVRPlugin.EnableControllerColliders.Value; } - /// - /// Links V2 dynamic bones to a controller collider - /// - internal static void AddColliderToDBv2(DynamicBoneCollider collider, DynamicBone_Ver02[] dynamicBones, Regex boneNameMatcher = null) + private static void AddCollidersToBone(Component bone) { - if (collider == null) return; - if (dynamicBones.Length == 0) return; - - int newDBCount = 0; - - //For each heroine dynamic bone, add controller collider - for (int z = 0; z < dynamicBones.Length; z++) - { - // var toLog = "Bone " + dynamicBones[z].name + " colliders: "; - // foreach (var c in dynamicBones[z].Colliders) toLog += c.name; - // BetterVRPlugin.Logger.LogInfo(toLog); - - //Check for existing interaction - if (dynamicBones[z].Colliders.Contains(collider)) continue; - if (boneNameMatcher != null && !boneNameMatcher.IsMatch(dynamicBones[z].name)) continue; - dynamicBones[z].Colliders.Add(collider); - newDBCount++; - } - - if (newDBCount > 0 && BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" Linked {newDBCount} new V2 colliders"); + AddColliderToBone(leftControllerCollider, bone); + AddColliderToBone(rightControllerCollider, bone); + AddColliderToBone(mouthCollider, bone); + AddColliderToBone(floorCollider, bone); + AddColliderToBone(rightControllerCollider, bone); + AddColliderToBone(BetterVRPluginHelper.leftGlove?.GetComponent()?.indexCollider, bone, INDEX_COLLIDING_BONE_MATCHER); + AddColliderToBone(BetterVRPluginHelper.rightGlove?.GetComponent()?.indexCollider, bone, INDEX_COLLIDING_BONE_MATCHER); } - /// - /// Links V1 dynamic bones to a controller collider - /// - internal static void AddColliderToDB(DynamicBoneCollider collider, DynamicBone[] dynamicBones, Regex boneNameMatcher = null) - { + private static void AddColliderToBone(DynamicBoneCollider collider, Component bone, Regex boneNameMatcher = null) + { if (collider == null) return; - if (dynamicBones.Length == 0) return; - - int newDBCount = 0; + if (boneNameMatcher != null && !boneNameMatcher.IsMatch(bone.name)) return; - //For each heroine dynamic bone, add controller collider - for (int z = 0; z < dynamicBones.Length; z++) + if (bone is DynamicBone) { - // var toLog = "Bone " + dynamicBones[z].name + " colliders: "; - // foreach (var c in dynamicBones[z].m_Colliders) toLog += c.name; - // BetterVRPlugin.Logger.LogInfo(toLog); - - //Check for existing interaction - if (dynamicBones[z].m_Colliders.Contains(collider)) continue; - if (boneNameMatcher != null && !boneNameMatcher.IsMatch(dynamicBones[z].name)) continue; - dynamicBones[z].m_Colliders.Add(collider); - newDBCount++; + var colliders = ((DynamicBone) bone).m_Colliders; + if (!colliders.Contains(collider)) colliders.Add(collider); } + if (bone is DynamicBone_Ver02) + { + var colliders = ((DynamicBone_Ver02)bone).Colliders; + if (!colliders.Contains(collider)) colliders.Add(collider); - if (newDBCount > 0 && BetterVRPlugin.debugLog) BetterVRPlugin.Logger.LogInfo($" Linked {newDBCount} new V1 colliders"); + } } } } From ba05fde38d6da6b6978c75118343f2b4a7801555 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:13:10 +0000 Subject: [PATCH 139/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index 4c397f8..94be3f0 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -12,7 +12,7 @@ namespace BetterVR public partial class BetterVRPlugin : BaseUnityPlugin { public const string GUID = "BetterVR"; - public const string Version = "0.46"; + public const string Version = "0.47"; internal static new ManualLogSource Logger { get; private set; } #if DEBUG From a9393dbe71e7fd3c11e6b3fa7164f2eb9d8f6580 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:13:27 +0000 Subject: [PATCH 140/252] Update release.cmd --- release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.cmd b/release.cmd index 7a14630..44d6339 100644 --- a/release.cmd +++ b/release.cmd @@ -1,7 +1,7 @@ ::Zips the dll into the correct directory structure for release ::Make sure to increment the version -set version=0.46 +set version=0.47 set name=HS2_BetterVR IF NOT EXIST "../release/%name%/BepInEx/plugins" MKDIR "../release/%name%/BepInEx/plugins" From fddc18b146ad6149d791de1b5a1c19bd4d7bb70b Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:19:14 +0000 Subject: [PATCH 141/252] Update VRGlove.cs --- BetterVR/VRGlove.cs | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/BetterVR/VRGlove.cs b/BetterVR/VRGlove.cs index d9a10f6..0a1f4ca 100644 --- a/BetterVR/VRGlove.cs +++ b/BetterVR/VRGlove.cs @@ -35,15 +35,12 @@ internal void StartRepositioning() void Update() { - Vector3 center; - Transform controllerModel = + Transform controllerCenter = handRole == HandRole.RightHand ? - BetterVRPluginHelper.FindRightControllerRenderModel(out center) : - BetterVRPluginHelper.FindLeftControllerRenderModel(out center); + BetterVRPluginHelper.rightControllerCenter : + BetterVRPluginHelper.leftControllerCenter; - bool shouldShowHand = - (BetterVRPlugin.HandDisplay.Value == "Gloves" || BetterVRPlugin.HandDisplay.Value == "GlovesAndControllers") && - controllerModel != null; + bool shouldShowHand = BetterVRPlugin.GlovesEnabled() && controllerCenter != null; bool isShowingHand = gloveRenderer.gameObject.activeSelf; gloveRenderer.gameObject.SetActive(shouldShowHand); @@ -58,6 +55,8 @@ void Update() // Parent the renderer to camera to make sure that the gloves stay in the renderer's bounds and do not get culled. gloveRenderer.transform.parent = camera.transform; gloveRenderer.transform.localPosition = Vector3.zero; + var bounds = gloveRenderer.GetComponent().bounds; + BetterVRPlugin.Logger.LogInfo("Glove renderer bounds: " + bounds); } if (isRepositioning) @@ -65,10 +64,12 @@ void Update() if (ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip) || ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip)) { - if (transform.parent != controllerModel.parent) transform.SetParent(controllerModel.parent, worldPositionStays: true); + // Pause repositioning + if (transform.parent != controllerCenter) transform.SetParent(controllerCenter, worldPositionStays: true); } else { + // Resume repositioning if (transform.parent != null) transform.SetParent(null, worldPositionStays: true); } @@ -78,25 +79,31 @@ void Update() ViveInput.GetPressDownEx(HandRole.RightHand, ControllerButton.AKey)) { isRepositioning = false; - transform.SetParent(controllerModel.parent, worldPositionStays: true); - var offset = controllerModel.InverseTransformVector(transform.position - center); + transform.SetParent(controllerCenter, worldPositionStays: true); if (handRole == HandRole.LeftHand) { BetterVRPlugin.LeftGloveRotation.Value = transform.localRotation; - BetterVRPlugin.LeftGloveOffset.Value = offset; + BetterVRPlugin.LeftGloveOffset.Value = transform.localPosition; } else { BetterVRPlugin.RightGloveRotation.Value = transform.localRotation; - BetterVRPlugin.RightGloveOffset.Value = offset; + BetterVRPlugin.RightGloveOffset.Value = transform.localPosition; } - BetterVRPlugin.Logger.LogInfo("Set hand offset: " + offset + " rotation: " + transform.localRotation.eulerAngles); + BetterVRPlugin.Logger.LogInfo("Set hand offset: " + transform.localPosition + " rotation: " + transform.localRotation.eulerAngles); } return; } - if (transform.parent != controllerModel.parent) transform.parent = controllerModel.parent; + if (transform.parent != controllerCenter) + { + transform.parent = controllerCenter; + transform.localRotation = + handRole == HandRole.RightHand ? BetterVRPlugin.RightGloveRotation.Value : BetterVRPlugin.LeftGloveRotation.Value; + transform.localPosition = + handRole == HandRole.RightHand ? BetterVRPlugin.RightGloveOffset.Value : BetterVRPlugin.LeftGloveOffset.Value; + } if (transform.parent == null) return; @@ -104,9 +111,8 @@ void Update() transform.localScale = Vector3.one * BetterVRPlugin.GloveScale.Value; transform.localRotation = handRole == HandRole.RightHand ? BetterVRPlugin.RightGloveRotation.Value : BetterVRPlugin.LeftGloveRotation.Value; - Vector3 offsetFromCenter = + transform.localPosition = handRole == HandRole.RightHand ? BetterVRPlugin.RightGloveOffset.Value : BetterVRPlugin.LeftGloveOffset.Value; - transform.position = center + controllerModel.transform.TransformVector(offsetFromCenter); } private static void LoadGloves() From 8a59d2fbdf1b5de2979e4c2cbc56c648532f5842 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:19:36 +0000 Subject: [PATCH 142/252] Update HandHeldToy.cs --- BetterVR/HandHeldToy.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/BetterVR/HandHeldToy.cs b/BetterVR/HandHeldToy.cs index 1a2f326..8f9edee 100644 --- a/BetterVR/HandHeldToy.cs +++ b/BetterVR/HandHeldToy.cs @@ -45,22 +45,22 @@ void Update() if (ViveInput.GetPressDownEx(HandRole.LeftHand, ControllerButton.Grip)) { - var controllerModel = BetterVRPluginHelper.FindLeftControllerRenderModel(out var center); - if (controllerModel != null & GrabDistance(center) < controllerModel.transform.lossyScale.x * GRAB_RANGE) + var controllerCenter = BetterVRPluginHelper.leftControllerCenter; + if (controllerCenter != null && + GrabDistance(controllerCenter.position) < controllerCenter.transform.lossyScale.x * GRAB_RANGE) { hSpeedGesture.roleProperty = VRControllerInput.roleL; - AttachAndBringToRangeOf(controllerModel); + AttachAndBringToRangeOf(controllerCenter); } } else if (ViveInput.GetPressDownEx(HandRole.RightHand, ControllerButton.Grip)) { - var controllerModel = BetterVRPluginHelper.FindRightControllerRenderModel(out var center); - if (controllerModel != null & GrabDistance(center) < controllerModel.transform.lossyScale.x * GRAB_RANGE) + var controllerCenter = BetterVRPluginHelper.rightControllerCenter; + if (controllerCenter != null && GrabDistance(controllerCenter.position) < controllerCenter.transform.lossyScale.x * GRAB_RANGE) { hSpeedGesture.roleProperty = VRControllerInput.roleR; - AttachAndBringToRangeOf(controllerModel); + AttachAndBringToRangeOf(controllerCenter); } - } else if ( !IsAttachedToBody() && @@ -91,11 +91,11 @@ internal void CycleMode(bool isRightHand) // Bring the newly appeared object into range of hand. if (isRightHand) { - AttachAndBringToRangeOf(BetterVRPluginHelper.FindRightControllerRenderModel(out var center)); + AttachAndBringToRangeOf(BetterVRPluginHelper.leftControllerCenter); } else { - AttachAndBringToRangeOf(BetterVRPluginHelper.FindLeftControllerRenderModel(out var center)); + AttachAndBringToRangeOf(BetterVRPluginHelper.rightControllerCenter); } transform.SetParent(null, worldPositionStays: true); } From 9d59f5278f51cf20e826d5bd54379eca91fc06fb Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:20:16 +0000 Subject: [PATCH 143/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index 8cf2147..643a0f9 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -78,7 +78,8 @@ internal static void MaybeRestoreVrOriginTransform() } // Stop attempting to restore camera transform if there is any input that might move the camera. - if (BetterVRPluginHelper.LeftHandGripPress() || BetterVRPluginHelper.RightHandGripPress() || + if (ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip) || + ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip) || Mathf.Abs(BetterVRPluginHelper.GetRightHandPadStickCombinedOutput().x) > 0.25f || !Manager.HSceneManager.isHScene) { ClearRecordedVrOriginTransform(); @@ -93,12 +94,18 @@ internal static void UpdateSqueezeMovement() Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; if (!vrOrigin) return; - bool leftHandFullGrab = BetterVRPluginHelper.LeftHandGripPress() && BetterVRPluginHelper.LeftHandTriggerPress(); - bool rightHandFullGrab = BetterVRPluginHelper.RightHandGripPress() && BetterVRPluginHelper.RightHandTriggerPress(); - bool bothGrips = BetterVRPluginHelper.LeftHandGripPress() && BetterVRPluginHelper.RightHandGripPress(); + bool leftHandTriggerAndGrip = + ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Trigger) && + ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip); + bool rightHandTriggerAndGrip = + ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Trigger) && + ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip); + bool bothGrips = + ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip) && + ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip); bool twoHandedTurn = BetterVRPlugin.IsTwoHandedTurnEnabled() && bothGrips; - bool shouldScale = leftHandFullGrab && rightHandFullGrab; + bool shouldScale = leftHandTriggerAndGrip && rightHandTriggerAndGrip; twoHandedWorldGrab.enabled = shouldScale || twoHandedTurn; twoHandedWorldGrab.canScale = shouldScale; @@ -106,20 +113,16 @@ internal static void UpdateSqueezeMovement() bool allowOneHandedWorldGrab = !twoHandedWorldGrab.enabled && (BetterVRPlugin.IsOneHandedTurnEnabled() || BetterVRPlugin.IsTwoHandedTurnEnabled()); - // Check right hand - var rightControllerModel = BetterVRPluginHelper.FindRightControllerRenderModel(out var rCenter); - if (rightControllerModel) + if (BetterVRPluginHelper.leftControllerCenter) { - rightControllerModel.GetOrAddComponent().enabled = - rightHandFullGrab && !leftHandFullGrab && allowOneHandedWorldGrab; + BetterVRPluginHelper.leftControllerCenter.GetOrAddComponent().enabled = + leftHandTriggerAndGrip && !rightHandTriggerAndGrip && allowOneHandedWorldGrab; } - // Check left hand - var leftControllerModel = BetterVRPluginHelper.FindLeftControllerRenderModel(out var lCenter); - if (leftControllerModel) + if (BetterVRPluginHelper.rightControllerCenter) { - leftControllerModel.GetOrAddComponent().enabled = - leftHandFullGrab && !rightHandFullGrab && allowOneHandedWorldGrab; + BetterVRPluginHelper.rightControllerCenter.GetOrAddComponent().enabled = + rightHandTriggerAndGrip && !leftHandTriggerAndGrip && allowOneHandedWorldGrab; } if (!isDraggingScale && bothGrips && From c9f633e23e3c4843cd96a7ea6a9c25d62b386346 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:20:56 +0000 Subject: [PATCH 144/252] Update VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 106 +++++++++++++++++--------- 1 file changed, 69 insertions(+), 37 deletions(-) diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs index e72c5dc..f40a5c0 100644 --- a/BetterVR/VrController.StripUpdater.cs +++ b/BetterVR/VrController.StripUpdater.cs @@ -232,7 +232,7 @@ private static StripCollider FindClosestStripCollider(Vector3 position, float ra } } - internal struct ColliderAnatomy + public struct ColliderAnatomy { public ColliderAnatomy(byte clothType, Vector3? scale = null, Vector3? offset = null, float? radius = null) { @@ -264,12 +264,13 @@ public class StripColliderRegistry : MonoBehaviour { new Regex(@"LegLow01_[LR]$"), new ColliderAnatomy(5, scale: Vector3.one * 1.25f) }, // Pants { new Regex(@"LegLowRoll_[LR]$"), new ColliderAnatomy(6) }, // Socks { new Regex(@"Foot01_[LR]$"), new ColliderAnatomy(7) }, // Shoes - { new Regex(@"cf_J_Neck$"), new ColliderAnatomy(8, Vector3.one * 1.25f) } // No cloth, for touching only + { new Regex(@"cf_J_Neck$"), new ColliderAnatomy(8, Vector3.one * 1.25f) }, // No cloth, for touching only + { new Regex(@"N_Mouth$"), new ColliderAnatomy(8, Vector3.one * 0.5f) } // No cloth, for touching only }; private bool hasAddedColliders = false; private ChaControl character; - private List colliders = new List(); + private List colliders = new List(); internal void Init(ChaControl chaControl) { @@ -292,7 +293,7 @@ void OnDestroy() RemoveColliders(); } - public void RemoveAndDestroyCollider(StripCollider collider) + public void RemoveAndDestroyCollider(InteractionCollider collider) { colliders.Remove(collider); if (collider.gameObject) Destroy(collider.gameObject); @@ -300,7 +301,7 @@ public void RemoveAndDestroyCollider(StripCollider collider) private void RemoveColliders() { - foreach (StripCollider collider in colliders) + foreach (var collider in colliders) { if (collider == null || collider.gameObject == null) continue; GameObject.Destroy(collider.gameObject); @@ -328,66 +329,49 @@ private void AddColliderInChildren(Transform transform) var collider = StripCollider.Create(character, NAME_MATCHER_TO_ANATOMY[key], transform, null); collider.name = transform.name + COLLIDER_SUFFIX; colliders.Add(collider); - BetterVRPlugin.Logger.LogDebug("Added strip collider for " + transform.name + " on " + character.name); + BetterVRPlugin.Logger.LogDebug("Added interaction collider for " + transform.name + " on " + character.name); break; } } } - public class StripCollider : MonoBehaviour + public class StripCollider : InteractionCollider { public byte clothType { get; private set; } public byte stripLevel { get { return IsValidClothType(clothType) ? character.fileStatus.clothesState[clothType] : (byte)0; } } - private ChaControl character; - internal static bool IsValidClothType(byte i) { return 0 <= i && i < 8; } + internal static bool IsValidClothType(byte i) { return 0 <= i && i < 8; } - internal static StripCollider Create( + internal static new InteractionCollider Create( ChaControl character, ColliderAnatomy anatomy, Transform parent, Transform scaleReference, bool shouldRender = false) { - StripCollider collider = CreateSphere(anatomy, parent, scaleReference, shouldRender).GetOrAddComponent(); - collider.Init(character, anatomy.clothType); - return collider; - } + if (!IsValidClothType(anatomy.clothType)) + { + return InteractionCollider.Create(character, anatomy, parent, scaleReference, shouldRender); + } - internal static GameObject CreateSphere( - ColliderAnatomy anatomy, Transform parent, Transform scaleReference, bool shouldRender = false) - { - GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); - sphere.transform.parent = scaleReference; - sphere.transform.localScale = anatomy.scale; - sphere.transform.parent = parent; - sphere.transform.localPosition = anatomy.offset; - sphere.transform.localRotation = Quaternion.identity; - var collider = sphere.GetOrAddComponent(); - collider.isTrigger = true; - collider.radius = anatomy.radius; - var renderer = sphere.GetComponent(); + var collider = CreateSphere(anatomy, parent, scaleReference, shouldRender).GetOrAddComponent(); + collider.Init(character, anatomy.clothType); + var renderer = collider.GetComponent(); if (shouldRender) { - renderer.material.color = - IsValidClothType(anatomy.clothType) ? StripUpdater.STRIP_INDICATOR_COLORS[anatomy.clothType] : Color.gray; + renderer.material.color = StripUpdater.STRIP_INDICATOR_COLORS[anatomy.clothType]; } else { - Object.Destroy(renderer); + Destroy(renderer); } - return sphere; + return collider; } internal void Init(ChaControl character, byte clothType) { - this.character = character; + base.Init(character); this.clothType = clothType; } - internal bool IsCharacterVisible() - { - return character != null && character.isActiveAndEnabled && character.visibleAll; - } - internal bool IsInteractable() { return IsCharacterVisible() && IsValidClothType(clothType) && character.IsClothes(clothType); @@ -412,4 +396,52 @@ internal void Clothe() character.SetClothesState(clothType, 0); } } + + public class InteractionCollider : MonoBehaviour + { + protected ChaControl character; + + internal static InteractionCollider Create( + ChaControl character, ColliderAnatomy anatomy, + Transform parent, Transform scaleReference, bool shouldRender = false) + { + var collider = CreateSphere(anatomy, parent, scaleReference, shouldRender).GetOrAddComponent(); + collider.Init(character); + return collider; + } + + protected static GameObject CreateSphere( + ColliderAnatomy anatomy, Transform parent, Transform scaleReference, bool shouldRender = false) + { + GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); + sphere.transform.parent = scaleReference; + sphere.transform.localScale = anatomy.scale; + sphere.transform.parent = parent; + sphere.transform.localPosition = anatomy.offset; + sphere.transform.localRotation = Quaternion.identity; + var collider = sphere.GetOrAddComponent(); + collider.isTrigger = true; + collider.radius = anatomy.radius; + var renderer = sphere.GetComponent(); + if (shouldRender) + { + renderer.material.color = Color.gray; + } + else + { + Object.Destroy(renderer); + } + return sphere; + } + + internal void Init(ChaControl character) + { + this.character = character; + } + + internal bool IsCharacterVisible() + { + return character != null && character.isActiveAndEnabled && character.visibleAll; + } + } } From 2efd838ce7e277c321a96a0299955fbf46387559 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:22:52 +0000 Subject: [PATCH 145/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index 553f40e..ee88f11 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -7,9 +7,11 @@ namespace BetterVR { public class HSpeedGesture : MonoBehaviour { + private static readonly Regex ULTRA_SENSITIVE_COLLIDER_NAME_MATCHER = new Regex(@"agina|okan"); private static readonly Regex SENSITIVE_COLLIDER_NAME_MATCHER = new Regex(@"[Mm]une|[Cc]hest|agina|okan"); - private static readonly Regex MILD_COLLIDER_NAME_MATCHER = new Regex(@"[Nn]eck|[Ll]eg|[Ss]iri|[Bb]elly"); + private static readonly Regex MILD_COLLIDER_NAME_MATCHER = new Regex(@"[Nn]eck|[Ll]eg|[Ss]iri|[Bb]elly|[Mm]outh"); private static readonly Regex SPNKABLE_COLLIDER_NAME_MATCHER = new Regex(@"[Ll]eg|[Ss]iri"); + private static readonly Regex MOUTH_MATCHER = new Regex(@"[Mm]outh"); internal ViveRoleProperty roleProperty; internal Transform capsuleStart; @@ -154,8 +156,8 @@ private bool ShouldBeTouching(float speed) Collider[] colliders = Physics.OverlapCapsule(capsuleStart.position, capsuleEnd.position, activationRadius * scale); foreach (var collider in colliders) { - var stripCollider = collider.GetComponent(); - if (stripCollider == null || !stripCollider.IsCharacterVisible()) continue; + var interactionCollider = collider.GetComponent(); + if (interactionCollider == null || !interactionCollider.IsCharacterVisible()) continue; if (SENSITIVE_COLLIDER_NAME_MATCHER.IsMatch(collider.name)) { @@ -166,6 +168,7 @@ private bool ShouldBeTouching(float speed) if (MILD_COLLIDER_NAME_MATCHER.IsMatch(collider.name)) { + if (roleProperty != VRControllerInput.roleH && MOUTH_MATCHER.IsMatch(collider.name)) continue; interactingCollider = collider; isColliderSensitive = false; } @@ -196,9 +199,16 @@ private void UpdateSmoothTargetSpeed(float speedInput, HSceneFlagCtrl hCtrl) } var targetSpeed = Mathf.Clamp(speedInput - 0.125f, 0, 2f); - - // Curve speed output to require faster movement. - if (hCtrl.loopType == 2) targetSpeed *= (targetSpeed / 2); + + if (hCtrl.loopType == 2) + { + // Curve speed output to require faster movement. + targetSpeed *= (targetSpeed / 2); + } + else if (ULTRA_SENSITIVE_COLLIDER_NAME_MATCHER.IsMatch(interactingCollider.name)) { + // Curve speed output to require slower movement. + targetSpeed = Mathf.Sqrt(targetSpeed * 2); + } if (targetSpeed <= receiver.smoothTargetSpeed) return; @@ -217,6 +227,8 @@ public class HSpeedGestureReceiver : MonoBehaviour internal const float LOOP_01_DIVIDER = 1f; // This number is from the vanilla game internal const float LOOP_1_DEACTIVATION_THRESHOLD = 0.125f; internal const float LOOP_1_ACTIVATION_THRESHOLD = 1.5f; + internal const float ORIGINAL_SPEED_GAUGE_RATE = 0.01f; + internal const float CUSTOM_SPEED_GAUGE_RATE = 1f / 256; internal static float outputY { get; private set; } private static FieldInfo modeCtrlField; @@ -235,7 +247,12 @@ void FixedUpdate() (gaugeHitIndicator ?? (gaugeHitIndicator = new GaugeHitIndicator())).UpdateIndicators(isEffective); var hCtrl = Singleton.Instance; - if (!isEffective || !hCtrl) + if (!hCtrl) return; + + // Reduce feel increase rate for realism. + hCtrl.speedGuageRate = isEffective ? CUSTOM_SPEED_GAUGE_RATE : ORIGINAL_SPEED_GAUGE_RATE; + + if (!isEffective) { outputY = 0; return; @@ -249,7 +266,7 @@ void FixedUpdate() // Allow stopping action with hand motion in Aibu mode. StopMotion(hCtrl); } - + if (hCtrl.isGaugeHit && hCtrl.feel_f > 0.99f && hCtrl.feel_m > 0.75f) BetterVRPluginHelper.TryFinishHSameTime(); // BetterVRPlugin.Logger.LogWarning( From 51edee2108c0f6bd7c786fdec08e8d2569a5533d Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 22:52:31 +0000 Subject: [PATCH 146/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index 94be3f0..e6c8cc0 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -84,7 +84,9 @@ internal static AIChara.ChaControl GetPlayer() private static void CheckRadialMenu(RadialMenu radialMenu, HandRole handRole) { - bool menuShouldBeActive = ViveInput.GetPressEx(handRole, ControllerButton.AKey); + bool menuShouldBeActive = + ViveInput.GetPressDownEx(handRole, ControllerButton.AKey) || + (radialMenu.isActiveAndEnabled && ViveInput.GetPressEx(handRole, ControllerButton.AKey)); if (menuShouldBeActive && !radialMenu.gameObject.activeSelf) { radialMenu.gameObject.SetActive(true); @@ -132,6 +134,7 @@ private static void CheckRadialMenu(RadialMenu radialMenu, HandRole handRole) break; case 5: if (!isTriggerUp) break; + radialMenu.gameObject.SetActive(false); BetterVRPluginHelper.ResetView(); BetterVRPluginHelper.UpdateControllersVisibilty(); VRControllerCollider.UpdateDynamicBoneColliders(); From e281c0d4014d1e3a166fb3a70ed0a645b3635bad Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 23:24:49 +0000 Subject: [PATCH 147/252] Update HandHeldToy.cs --- BetterVR/HandHeldToy.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BetterVR/HandHeldToy.cs b/BetterVR/HandHeldToy.cs index 8f9edee..954bca2 100644 --- a/BetterVR/HandHeldToy.cs +++ b/BetterVR/HandHeldToy.cs @@ -91,11 +91,11 @@ internal void CycleMode(bool isRightHand) // Bring the newly appeared object into range of hand. if (isRightHand) { - AttachAndBringToRangeOf(BetterVRPluginHelper.leftControllerCenter); + AttachAndBringToRangeOf(BetterVRPluginHelper.rightControllerCenter); } else { - AttachAndBringToRangeOf(BetterVRPluginHelper.rightControllerCenter); + AttachAndBringToRangeOf(BetterVRPluginHelper.leftControllerCenter); } transform.SetParent(null, worldPositionStays: true); } From 1bd55920ee5bb195dccd6be59b7e419e02e1a3b6 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 23:26:47 +0000 Subject: [PATCH 148/252] Update GaugeHitIndicator.cs --- BetterVR/GaugeHitIndicator.cs | 49 +++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/BetterVR/GaugeHitIndicator.cs b/BetterVR/GaugeHitIndicator.cs index 8c97df3..72e54c8 100644 --- a/BetterVR/GaugeHitIndicator.cs +++ b/BetterVR/GaugeHitIndicator.cs @@ -25,7 +25,7 @@ private TextMeshPro leftHandIndicator { get { - if (!_leftHandIndicator) _leftHandIndicator = CreateIndicator(BetterVRPluginHelper.leftCursorAttach); + if (!_leftHandIndicator) _leftHandIndicator = CreateIndicator(BetterVRPluginHelper.leftControllerCenter); return _leftHandIndicator; } } @@ -33,7 +33,7 @@ private TextMeshPro rightHandIndicator { get { - if (!_rightHandIndicator) _rightHandIndicator = CreateIndicator(BetterVRPluginHelper.rightCursorAttach); + if (!_rightHandIndicator) _rightHandIndicator = CreateIndicator(BetterVRPluginHelper.rightControllerCenter); return _rightHandIndicator; } } @@ -74,21 +74,28 @@ internal void UpdateIndicators(bool isHSpeedGestureEffective) if (camera && vrOrigin) { + leftHandIndicator.transform.localPosition = + leftHandIndicator.transform.parent.InverseTransformDirection(vrOrigin.transform.up) * 0.0625f; + rightHandIndicator.transform.localPosition = + rightHandIndicator.transform.parent.InverseTransformDirection(vrOrigin.transform.up) * 0.0625f; + headIndicator.transform.position = + Vector3.SmoothDamp( + headIndicator.transform.position, + camera.transform.TransformPoint(0, 0.25f, 0.75f), + ref headIndicatorVelocity, + 1f); + leftHandIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); rightHandIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); headIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); - headIndicator.transform.position = - Vector3.SmoothDamp( - headIndicator.transform.position, - camera.transform.TransformPoint(0, 0.3125f, 0.75f), - ref headIndicatorVelocity, - 1f); + } } private bool IsGaugeHit() { - return Singleton.Instance?.isGaugeHit ?? false; + var ctrl = Singleton.Instance; + return ctrl != null && ctrl.isGaugeHit && ctrl.loopType != -1; } private float GetFeelLevel() @@ -98,19 +105,30 @@ private float GetFeelLevel() private void UpdateIndicatorSizeAndColor() { - Color color = Color.Lerp(START_COLOR, FINISH_COLOR, GetFeelLevel()); + var feelLevel = GetFeelLevel(); + Color color; + if (feelLevel > 0.98 || (feelLevel > 0.74f && feelLevel < 0.75f)) + { + // Pulsing color + color = Color.Lerp(FINISH_COLOR, Color.white, Mathf.Abs((Time.time / 0.25f) % 2 - 1)); + } + else + { + color = Color.Lerp(START_COLOR, FINISH_COLOR, feelLevel); + } + if (headIndicator) { - headIndicator.transform.localScale = Vector3.one * 0.03f * smoothGaugeHit; + headIndicator.transform.localScale = Vector3.one * smoothGaugeHit / 32; headIndicator.color = color; } if (leftHandIndicator) { - leftHandIndicator.transform.localScale = Vector3.one * 0.02f * smoothGaugeHit; + leftHandIndicator.transform.localScale = Vector3.one * smoothGaugeHit / 64; leftHandIndicator.color = color; } if (rightHandIndicator) { - rightHandIndicator.transform.localScale = Vector3.one * 0.02f * smoothGaugeHit; + rightHandIndicator.transform.localScale = Vector3.one * smoothGaugeHit / 64; rightHandIndicator.color = color; } } @@ -121,11 +139,14 @@ private static TextMeshPro CreateIndicator(Transform cursorAttach) var textMesh = new GameObject().AddComponent().gameObject.AddComponent(); textMesh.transform.SetParent(cursorAttach); - textMesh.transform.localPosition = Vector3.back * 0.0625f; textMesh.text = "\u2665"; textMesh.fontSize = 16; textMesh.color = new Color(1, 0.25f, 0.25f); textMesh.alignment = TextAlignmentOptions.Center; + // var material = textMesh.fontMaterial; + // material.renderQueue = (int) UnityEngine.Rendering.RenderQueue.Overlay; + // textMesh.fontMaterial = material; + // textMesh.sort return textMesh; } } From ddf7902972588f686b779dc8db813b098de2373c Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sat, 6 Jan 2024 23:47:41 +0000 Subject: [PATCH 149/252] Update GaugeHitIndicator.cs --- BetterVR/GaugeHitIndicator.cs | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/BetterVR/GaugeHitIndicator.cs b/BetterVR/GaugeHitIndicator.cs index 72e54c8..e87eb20 100644 --- a/BetterVR/GaugeHitIndicator.cs +++ b/BetterVR/GaugeHitIndicator.cs @@ -42,7 +42,9 @@ internal void UpdateIndicators(bool isHSpeedGestureEffective) { if (!leftHandIndicator || !rightHandIndicator || !headIndicator) return; - if (IsGaugeHit() && (isHSpeedGestureEffective || smoothGaugeHit > 0)) + bool isGaugeHit = IsGaugeHit(); + + if (isGaugeHit && (isHSpeedGestureEffective || smoothGaugeHit > 0)) { leftHandIndicator.gameObject.SetActive(true); rightHandIndicator.gameObject.SetActive(true); @@ -52,7 +54,7 @@ internal void UpdateIndicators(bool isHSpeedGestureEffective) else if (!leftHandIndicator.isActiveAndEnabled && !rightHandIndicator.isActiveAndEnabled && !headIndicator.isActiveAndEnabled) { return; - } + } else { smoothGaugeHit = Mathf.SmoothDamp(smoothGaugeHit, -0.125f, ref acceleration, 0.25f); @@ -67,7 +69,7 @@ internal void UpdateIndicators(bool isHSpeedGestureEffective) } } - UpdateIndicatorSizeAndColor(); + UpdateIndicatorSizeAndColor(isGaugeHit); var camera = BetterVRPluginHelper.VRCamera; var vrOrigin = BetterVRPluginHelper.VROrigin; @@ -103,26 +105,21 @@ private float GetFeelLevel() return Singleton.Instance?.feel_f ?? 0; } - private void UpdateIndicatorSizeAndColor() + private void UpdateIndicatorSizeAndColor(bool isGaugeHit) { var feelLevel = GetFeelLevel(); - Color color; - if (feelLevel > 0.98 || (feelLevel > 0.74f && feelLevel < 0.75f)) - { - // Pulsing color - color = Color.Lerp(FINISH_COLOR, Color.white, Mathf.Abs((Time.time / 0.25f) % 2 - 1)); - } - else - { - color = Color.Lerp(START_COLOR, FINISH_COLOR, feelLevel); - } + Color color = + ShouldUsePulsingColor(isGaugeHit, feelLevel) ? + Color.Lerp(FINISH_COLOR, Color.white, Mathf.Abs((Time.time * 4) % 2 - 1)) : + Color.Lerp(START_COLOR, FINISH_COLOR, feelLevel); if (headIndicator) { headIndicator.transform.localScale = Vector3.one * smoothGaugeHit / 32; headIndicator.color = color; } - if (leftHandIndicator) { + if (leftHandIndicator) + { leftHandIndicator.transform.localScale = Vector3.one * smoothGaugeHit / 64; leftHandIndicator.color = color; } @@ -133,6 +130,13 @@ private void UpdateIndicatorSizeAndColor() } } + private static bool ShouldUsePulsingColor(bool isGaugeHit, float feelLevel) + { + if (!isGaugeHit) return false; + if (feelLevel > 0.735f && feelLevel < 0.75f) return true; + return feelLevel > 0.975f; + } + private static TextMeshPro CreateIndicator(Transform cursorAttach) { if (!cursorAttach) return null; From dafab83e6388debef6eb52380d942c31a880abf7 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 7 Jan 2024 00:08:38 +0000 Subject: [PATCH 150/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index ee88f11..a8649be 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -303,7 +303,7 @@ internal float GetOutput(HSceneFlagCtrl hCtrl) internal float GetAccelerationFactor(HSceneFlagCtrl ctrl) { // Damp the speed more when it is in gauge hit zone to avoid voice flickering. - if (ctrl.isGaugeHit && smoothTargetSpeed > 0.125f) return 0.125f / smoothTargetSpeed; + if (ctrl.isGaugeHit) return smoothTargetSpeed <= 1 ? 0.125f : 0.125f / smoothTargetSpeed; // Damp the speed to delay starting Aibu. if (ctrl.loopType == -1) return 0.375f; From b7a2653877edf016fce968e52b7b74d5b0be9cdb Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 7 Jan 2024 00:23:47 +0000 Subject: [PATCH 151/252] Update VRController.Hooks.cs --- BetterVR/VRController.Hooks.cs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/BetterVR/VRController.Hooks.cs b/BetterVR/VRController.Hooks.cs index 5374007..6a18a96 100644 --- a/BetterVR/VRController.Hooks.cs +++ b/BetterVR/VRController.Hooks.cs @@ -50,6 +50,24 @@ internal static bool ControllerMovePatch() } [HarmonyPrefix, HarmonyPatch(typeof(HScene), "GetAxis")] + public static bool HSceneGetAxisPatch(HandRole _hand, ref Vector2 __result) + { + bool shouldFallback = PatchGetAxis(_hand, ref __result); + if (HSpeedGestureReceiver.outputY != 0) + { + __result.y += HSpeedGestureReceiver.outputY; + shouldFallback = false; + } + return shouldFallback; + } + + [HarmonyPrefix, HarmonyPatch(typeof(HSceneSpriteFinishCategory), "GetAxis")] + public static bool HSceneSpriteCategoryGetAxisPatch(HandRole _hand, ref Vector2 __result) + { + return PatchGetAxis(_hand, ref __result); + } + + [HarmonyPrefix, HarmonyPatch(typeof(HS2VR.GripMoveCrtl), "GetAxis")] public static bool PatchGetAxis(HandRole _hand, ref Vector2 __result) { if (_hand != HandRole.RightHand) @@ -61,8 +79,6 @@ public static bool PatchGetAxis(HandRole _hand, ref Vector2 __result) // This method works for Oculus controllers' thumbsticks too. var axis = BetterVRPluginHelper.GetRightHandPadStickCombinedOutput(); - axis.y += HSpeedGestureReceiver.outputY; - if (axis == Vector2.zero) return true; // The vanilla pad/thumb stick detection is half broken and does not work on some platforms, giving rise to the necessity of this patch. @@ -71,11 +87,6 @@ public static bool PatchGetAxis(HandRole _hand, ref Vector2 __result) return false; } - [HarmonyPrefix, HarmonyPatch(typeof(HS2VR.GripMoveCrtl), "GetAxis")] - public static bool GripMoveCrtlGetAxisPatch(HandRole _hand, ref Vector2 __result) - { - return PatchGetAxis(_hand, ref __result); - } // [HarmonyPostfix, HarmonyPatch(typeof(AIChara.ChaControl), nameof(AIChara.ChaControl.Initialize))] // internal static void ChaControlStartPatch(AIChara.ChaControl __instance, GameObject _objRoot) From 0de26ac53602d5030f6df9a696b6f37bf6212844 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 7 Jan 2024 02:01:25 +0000 Subject: [PATCH 152/252] Update VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 38 ++++++++++++++++----------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs index f40a5c0..aeebea7 100644 --- a/BetterVR/VrController.StripUpdater.cs +++ b/BetterVR/VrController.StripUpdater.cs @@ -208,7 +208,9 @@ private void UpdateStripIndicator() } clothIcons[i].SetActive(i == grabbedStripCollider.clothType); } - // if (BetterVRPluginHelper.VRCamera) clothIconCanvas.transform.LookAt(BetterVRPluginHelper.VRCamera.transform); + // if (BetterVRPluginHelper.VRCamera && BetterVRPluginHelper.VRCamera) { + // clothIconCanvas.transform.LookAt(BetterVRPluginHelper.VRCamera.transform, BetterVRPluginHelper.VROrigin.transform.up); + // } } private static StripCollider FindClosestStripCollider(Vector3 position, float range, byte minStripLevel = 0, byte maxStripLevel = 2) @@ -234,18 +236,20 @@ private static StripCollider FindClosestStripCollider(Vector3 position, float ra public struct ColliderAnatomy { - public ColliderAnatomy(byte clothType, Vector3? scale = null, Vector3? offset = null, float? radius = null) + public ColliderAnatomy(byte clothType, Vector3? scale = null, Vector3? offset = null, float? radius = null, int sensitivityLevel = 0) { this.clothType = clothType; this.scale = scale ?? Vector3.one; this.offset = offset ?? Vector3.zero; this.radius = radius ?? 0.5f; + this.sensitivityLevel = sensitivityLevel; } internal byte clothType; internal Vector3 scale; internal Vector3 offset; internal float radius; + internal int sensitivityLevel; } public class StripColliderRegistry : MonoBehaviour @@ -254,18 +258,18 @@ public class StripColliderRegistry : MonoBehaviour private static readonly Dictionary NAME_MATCHER_TO_ANATOMY = new Dictionary { { new Regex(@"Spine02$"), new ColliderAnatomy(0, scale: Vector3.one * 1.5f) }, // Top - { new Regex(@"Kosi01$"), new ColliderAnatomy(1, Vector3.one * 1.25f) }, // Bottom - { new Regex(@"Siri_[LR]$"), new ColliderAnatomy(1, Vector3.one * 1.25f, null, 0.75f) }, // Bottom - { new Regex(@"Belly_Mid_High"), new ColliderAnatomy(1, new Vector3(1f, 0.75f, 0.5f)) }, // Bottom - { new Regex(@"Mune_Nip01_[LR]$"), new ColliderAnatomy(2) }, // Top inner - { new Regex(@"Kokan$|agina_root$"), new ColliderAnatomy(3) }, // Under + { new Regex(@"Kosi01$"), new ColliderAnatomy(1, scale: Vector3.one * 1.25f) }, // Bottom + { new Regex(@"Siri_[LR]$"), new ColliderAnatomy(1, scale: Vector3.one * 1.25f, null, 0.75f, sensitivityLevel: 1) }, // Bottom + { new Regex(@"Belly_Mid_High"), new ColliderAnatomy(1, scale: new Vector3(1f, 0.75f, 0.5f), sensitivityLevel: 1) }, // Bottom + { new Regex(@"Mune_Nip01_[LR]$"), new ColliderAnatomy(2, sensitivityLevel: 2) }, // Top inner + { new Regex(@"Kokan$|agina_root$"), new ColliderAnatomy(3, sensitivityLevel: 3) }, // Under { new Regex(@"Wrist_dam_[LR]$"), new ColliderAnatomy(4, scale: Vector3.one * 0.5f) }, // Gloves - { new Regex(@"LegUp01_[LR]$"), new ColliderAnatomy(5, scale: new Vector3(1.5f, 2f, 1.5f), offset: Vector3.down * 2f) }, // Pants + { new Regex(@"LegUp01_[LR]$"), new ColliderAnatomy(5, scale: new Vector3(1.5f, 2f, 1.5f), offset: Vector3.down * 2f, sensitivityLevel: 1) }, // Pants { new Regex(@"LegLow01_[LR]$"), new ColliderAnatomy(5, scale: Vector3.one * 1.25f) }, // Pants { new Regex(@"LegLowRoll_[LR]$"), new ColliderAnatomy(6) }, // Socks { new Regex(@"Foot01_[LR]$"), new ColliderAnatomy(7) }, // Shoes - { new Regex(@"cf_J_Neck$"), new ColliderAnatomy(8, Vector3.one * 1.25f) }, // No cloth, for touching only - { new Regex(@"N_Mouth$"), new ColliderAnatomy(8, Vector3.one * 0.5f) } // No cloth, for touching only + { new Regex(@"cf_J_Neck$"), new ColliderAnatomy(8, scale: Vector3.one * 1.25f, sensitivityLevel: 1) }, // No cloth, for touching only + { new Regex(@"N_Mouth$"), new ColliderAnatomy(8, scale: Vector3.one * 0.5f) } // No cloth, for touching only }; private bool hasAddedColliders = false; @@ -353,7 +357,7 @@ public class StripCollider : InteractionCollider } var collider = CreateSphere(anatomy, parent, scaleReference, shouldRender).GetOrAddComponent(); - collider.Init(character, anatomy.clothType); + collider.Init(character, anatomy.sensitivityLevel, anatomy.clothType); var renderer = collider.GetComponent(); if (shouldRender) { @@ -366,9 +370,9 @@ public class StripCollider : InteractionCollider return collider; } - internal void Init(ChaControl character, byte clothType) + internal void Init(ChaControl character, int sensitivityLevel, byte clothType) { - base.Init(character); + base.Init(character, sensitivityLevel); this.clothType = clothType; } @@ -399,14 +403,15 @@ internal void Clothe() public class InteractionCollider : MonoBehaviour { - protected ChaControl character; + protected ChaControl character { get; private set; } + internal int sensitivityLevel { get; private set; } internal static InteractionCollider Create( ChaControl character, ColliderAnatomy anatomy, Transform parent, Transform scaleReference, bool shouldRender = false) { var collider = CreateSphere(anatomy, parent, scaleReference, shouldRender).GetOrAddComponent(); - collider.Init(character); + collider.Init(character, anatomy.sensitivityLevel); return collider; } @@ -434,9 +439,10 @@ protected static GameObject CreateSphere( return sphere; } - internal void Init(ChaControl character) + internal void Init(ChaControl character, int sensitivityLevel) { this.character = character; + this.sensitivityLevel = sensitivityLevel; } internal bool IsCharacterVisible() From 1449826f11cb7754b27f1fead4927c742bfa580f Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 7 Jan 2024 02:01:44 +0000 Subject: [PATCH 153/252] Update GaugeHitIndicator.cs --- BetterVR/GaugeHitIndicator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/GaugeHitIndicator.cs b/BetterVR/GaugeHitIndicator.cs index e87eb20..f3e9ee1 100644 --- a/BetterVR/GaugeHitIndicator.cs +++ b/BetterVR/GaugeHitIndicator.cs @@ -134,7 +134,7 @@ private static bool ShouldUsePulsingColor(bool isGaugeHit, float feelLevel) { if (!isGaugeHit) return false; if (feelLevel > 0.735f && feelLevel < 0.75f) return true; - return feelLevel > 0.975f; + return feelLevel > 0.985f; } private static TextMeshPro CreateIndicator(Transform cursorAttach) From 05524c3075749bc49c4673135febc9f5065d5c74 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 7 Jan 2024 02:02:01 +0000 Subject: [PATCH 154/252] Update HandHeldToy.cs --- BetterVR/HandHeldToy.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/HandHeldToy.cs b/BetterVR/HandHeldToy.cs index 954bca2..2017079 100644 --- a/BetterVR/HandHeldToy.cs +++ b/BetterVR/HandHeldToy.cs @@ -169,7 +169,7 @@ private void CorrectBodyAttach(bool smooth = false) // Make body attach face forward horizontally. var targetForward = Vector3.ProjectOnPlane(camera.transform.forward, bodyAttach.up); - var targetPosition = camera.transform.position; + var targetPosition = camera.transform.TransformPoint(Vector3.down * 0.1875f); if (!BetterVRPlugin.ToyMovesVerticallyWhenAttachedToBody.Value) { From 71dab87656d84feb067ed0ee0155da6c75dbbde8 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 7 Jan 2024 02:02:38 +0000 Subject: [PATCH 155/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index a8649be..f97bad9 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -7,9 +7,6 @@ namespace BetterVR { public class HSpeedGesture : MonoBehaviour { - private static readonly Regex ULTRA_SENSITIVE_COLLIDER_NAME_MATCHER = new Regex(@"agina|okan"); - private static readonly Regex SENSITIVE_COLLIDER_NAME_MATCHER = new Regex(@"[Mm]une|[Cc]hest|agina|okan"); - private static readonly Regex MILD_COLLIDER_NAME_MATCHER = new Regex(@"[Nn]eck|[Ll]eg|[Ss]iri|[Bb]elly|[Mm]outh"); private static readonly Regex SPNKABLE_COLLIDER_NAME_MATCHER = new Regex(@"[Ll]eg|[Ss]iri"); private static readonly Regex MOUTH_MATCHER = new Regex(@"[Mm]outh"); @@ -19,12 +16,12 @@ public class HSpeedGesture : MonoBehaviour internal float activationRadius = 0.25f; internal float deactivationDistance = 0.5f; internal float sensitivityMultiplier = 1; - internal Collider interactingCollider { get; private set; } + internal InteractionCollider interactingCollider { get; private set; } internal static Vector2 hitArea; private bool isTouching; - private bool isColliderSensitive; + private bool isColliderSensitive { get { return interactingCollider != null && interactingCollider.sensitivityLevel >= 2; } } private static HSpeedGestureReceiver receiver; private static FadingHaptic _leftHandHHaptic; private static FadingHaptic _rightHandHHaptic; @@ -69,7 +66,8 @@ void FixedUpdate() if (!hCtrl) return; float speed = - VivePose.GetVelocity(roleProperty).magnitude * BetterVRPlugin.HandHSpeedSensitivity.Value * sensitivityMultiplier; + VivePose.GetVelocity(roleProperty).magnitude * BetterVRPlugin.HandHSpeedSensitivity.Value * sensitivityMultiplier + + VivePose.GetAngularVelocity(roleProperty).magnitude * 0.0625f; isTouching = ShouldBeTouching(speed); if (!isTouching) return; @@ -137,7 +135,8 @@ private bool ShouldBeTouching(float speed) if (interactingCollider) { Vector3 capsuleCenter = Vector3.Lerp(capsuleStart.position, capsuleEnd.position, 0.5f); - if (Vector3.Distance(capsuleCenter, interactingCollider.ClosestPoint(capsuleCenter)) < deactivationDistance * scale) + var collider = interactingCollider.GetComponent(); + if (collider != null && Vector3.Distance(capsuleCenter, collider.ClosestPoint(capsuleCenter)) < deactivationDistance * scale) { // Staying in the range of the current collider, can stay touching return true; @@ -159,18 +158,21 @@ private bool ShouldBeTouching(float speed) var interactionCollider = collider.GetComponent(); if (interactionCollider == null || !interactionCollider.IsCharacterVisible()) continue; - if (SENSITIVE_COLLIDER_NAME_MATCHER.IsMatch(collider.name)) + if (interactionCollider.sensitivityLevel >= 2) { - interactingCollider = collider; - isColliderSensitive = true; + interactingCollider = interactionCollider; return true; } - if (MILD_COLLIDER_NAME_MATCHER.IsMatch(collider.name)) + if (interactionCollider.sensitivityLevel == 1) { - if (roleProperty != VRControllerInput.roleH && MOUTH_MATCHER.IsMatch(collider.name)) continue; - interactingCollider = collider; - isColliderSensitive = false; + interactingCollider = interactionCollider; + continue; + } + + if (roleProperty == VRControllerInput.roleH && MOUTH_MATCHER.IsMatch(collider.name)) + { + interactingCollider = interactionCollider; } } @@ -205,7 +207,7 @@ private void UpdateSmoothTargetSpeed(float speedInput, HSceneFlagCtrl hCtrl) // Curve speed output to require faster movement. targetSpeed *= (targetSpeed / 2); } - else if (ULTRA_SENSITIVE_COLLIDER_NAME_MATCHER.IsMatch(interactingCollider.name)) { + else if (interactingCollider.sensitivityLevel >= 3) { // Curve speed output to require slower movement. targetSpeed = Mathf.Sqrt(targetSpeed * 2); } @@ -267,7 +269,7 @@ void FixedUpdate() StopMotion(hCtrl); } - if (hCtrl.isGaugeHit && hCtrl.feel_f > 0.99f && hCtrl.feel_m > 0.75f) BetterVRPluginHelper.TryFinishHSameTime(); + if (hCtrl.isGaugeHit && hCtrl.feel_f > 0.998f && hCtrl.feel_m > 0.75f) BetterVRPluginHelper.TryFinishHSameTime(); // BetterVRPlugin.Logger.LogWarning( // "H Loop type: " + hCtrl.loopType + " current speed: " + hCtrl.speed + From 072ac92c86856d0ea1c17f29119cc34c2862f3c6 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 7 Jan 2024 17:09:35 +0000 Subject: [PATCH 156/252] Update VRMenu.Random.cs --- BetterVR/VRMenu.Random.cs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/BetterVR/VRMenu.Random.cs b/BetterVR/VRMenu.Random.cs index 02de599..b78286c 100644 --- a/BetterVR/VRMenu.Random.cs +++ b/BetterVR/VRMenu.Random.cs @@ -20,7 +20,6 @@ public enum FemaleIndex public static List females = new List(); public static List males = new List(); - /// /// When the Random button is presses, set a random female/male, and start the HScene /// @@ -255,6 +254,8 @@ internal static void AppendRandomButton(VRSelectScene __instance) OnSelectRandomBtn(); }); + __instance.GetOrAddComponent().randomButton = btn; + // if (BetterVRPlugin.debugLog) DebugTools.LogChildrenComponents(btnGOCopy); //Set back to parent on canvas @@ -285,4 +286,20 @@ internal static void VRSelectSceneStart() } -} \ No newline at end of file + internal class StartRandomOnKeyEnter : MonoBehaviour + { + internal Button randomButton; + + void Update() + { + if (Singleton.Instance == null || randomButton == null) return; + + if (Input.GetKeyDown("enter") || Input.GetKeyDown("return")) + { + randomButton.onClick.Invoke(); + Destroy(this); + } + } + } + +} From 8ffc13544ba57b9ca7152542977b1d9ffd71972f Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 7 Jan 2024 17:10:42 +0000 Subject: [PATCH 157/252] Update VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 102 ++++++++++++-------------- 1 file changed, 45 insertions(+), 57 deletions(-) diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs index aeebea7..6d7db87 100644 --- a/BetterVR/VrController.StripUpdater.cs +++ b/BetterVR/VrController.StripUpdater.cs @@ -13,6 +13,7 @@ public class StripUpdater { internal static readonly Color[] STRIP_INDICATOR_COLORS = new Color[] { Color.blue, Color.red, Color.cyan, Color.magenta, Color.yellow, Color.green, Color.white, Color.black }; + private const float STRIP_START_RANGE = 0.5f; private const float STRIP_MIN_DRAG_RANGE = 0.75f; private Canvas clothIconCanvas; @@ -24,6 +25,8 @@ public class StripUpdater private StripCollider grabbedStripCollider; private MeshRenderer stripIndicator; + + internal StripUpdater(ViveRoleProperty handRole) { this.handRole = handRole; @@ -261,13 +264,14 @@ public class StripColliderRegistry : MonoBehaviour { new Regex(@"Kosi01$"), new ColliderAnatomy(1, scale: Vector3.one * 1.25f) }, // Bottom { new Regex(@"Siri_[LR]$"), new ColliderAnatomy(1, scale: Vector3.one * 1.25f, null, 0.75f, sensitivityLevel: 1) }, // Bottom { new Regex(@"Belly_Mid_High"), new ColliderAnatomy(1, scale: new Vector3(1f, 0.75f, 0.5f), sensitivityLevel: 1) }, // Bottom - { new Regex(@"Mune_Nip01_[LR]$"), new ColliderAnatomy(2, sensitivityLevel: 2) }, // Top inner + { new Regex(@"N_Chest$"), new ColliderAnatomy(2, scale: Vector3.one * 1.25f) }, // Top inner { new Regex(@"Kokan$|agina_root$"), new ColliderAnatomy(3, sensitivityLevel: 3) }, // Under { new Regex(@"Wrist_dam_[LR]$"), new ColliderAnatomy(4, scale: Vector3.one * 0.5f) }, // Gloves { new Regex(@"LegUp01_[LR]$"), new ColliderAnatomy(5, scale: new Vector3(1.5f, 2f, 1.5f), offset: Vector3.down * 2f, sensitivityLevel: 1) }, // Pants { new Regex(@"LegLow01_[LR]$"), new ColliderAnatomy(5, scale: Vector3.one * 1.25f) }, // Pants { new Regex(@"LegLowRoll_[LR]$"), new ColliderAnatomy(6) }, // Socks { new Regex(@"Foot01_[LR]$"), new ColliderAnatomy(7) }, // Shoes + { new Regex(@"Mune_Nip01_[LR]$"), new ColliderAnatomy(8, sensitivityLevel: 2) }, // No cloth, for touching only { new Regex(@"cf_J_Neck$"), new ColliderAnatomy(8, scale: Vector3.one * 1.25f, sensitivityLevel: 1) }, // No cloth, for touching only { new Regex(@"N_Mouth$"), new ColliderAnatomy(8, scale: Vector3.one * 0.5f) } // No cloth, for touching only }; @@ -290,6 +294,7 @@ void Update() AddColliderInChildren(character.transform); hasAddedColliders = true; + BetterVRPluginHelper.UpdatePrivacyScreen(Color.black); } void OnDestroy() @@ -347,33 +352,23 @@ public class StripCollider : InteractionCollider internal static bool IsValidClothType(byte i) { return 0 <= i && i < 8; } - internal static new InteractionCollider Create( - ChaControl character, ColliderAnatomy anatomy, - Transform parent, Transform scaleReference, bool shouldRender = false) + internal static InteractionCollider Create( + ChaControl character, ColliderAnatomy anatomy, Transform parent, Transform scaleReference) { + var gameObject = new GameObject(); + if (!IsValidClothType(anatomy.clothType)) { - return InteractionCollider.Create(character, anatomy, parent, scaleReference, shouldRender); - } - - var collider = CreateSphere(anatomy, parent, scaleReference, shouldRender).GetOrAddComponent(); - collider.Init(character, anatomy.sensitivityLevel, anatomy.clothType); - var renderer = collider.GetComponent(); - if (shouldRender) - { - renderer.material.color = StripUpdater.STRIP_INDICATOR_COLORS[anatomy.clothType]; - } - else - { - Destroy(renderer); + var collider = gameObject.AddComponent(); + collider.Init(character, anatomy, parent, scaleReference); + return collider; } - return collider; - } - - internal void Init(ChaControl character, int sensitivityLevel, byte clothType) - { - base.Init(character, sensitivityLevel); - this.clothType = clothType; + + var stripCollider = gameObject.AddComponent(); + stripCollider.Init(character, anatomy, parent, scaleReference); + stripCollider.clothType = anatomy.clothType; + stripCollider.color = StripUpdater.STRIP_INDICATOR_COLORS[anatomy.clothType]; + return stripCollider; } internal bool IsInteractable() @@ -403,46 +398,39 @@ internal void Clothe() public class InteractionCollider : MonoBehaviour { - protected ChaControl character { get; private set; } + internal static bool shouldVisualizeColliders = false; + + internal SphereCollider sphereCollider { get; private set; } internal int sensitivityLevel { get; private set; } + internal Color color { set { if (visualizer) visualizer.material.color = value; } } + + protected ChaControl character { get; private set; } + private MeshRenderer visualizer; - internal static InteractionCollider Create( - ChaControl character, ColliderAnatomy anatomy, - Transform parent, Transform scaleReference, bool shouldRender = false) + void Awake() { - var collider = CreateSphere(anatomy, parent, scaleReference, shouldRender).GetOrAddComponent(); - collider.Init(character, anatomy.sensitivityLevel); - return collider; + sphereCollider = gameObject.GetOrAddComponent(); } - protected static GameObject CreateSphere( - ColliderAnatomy anatomy, Transform parent, Transform scaleReference, bool shouldRender = false) - { - GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); - sphere.transform.parent = scaleReference; - sphere.transform.localScale = anatomy.scale; - sphere.transform.parent = parent; - sphere.transform.localPosition = anatomy.offset; - sphere.transform.localRotation = Quaternion.identity; - var collider = sphere.GetOrAddComponent(); - collider.isTrigger = true; - collider.radius = anatomy.radius; - var renderer = sphere.GetComponent(); - if (shouldRender) - { - renderer.material.color = Color.gray; - } - else + internal void Init(ChaControl character, ColliderAnatomy anatomy, Transform parent, Transform scaleReference) { + this.character = character; + transform.parent = scaleReference; + transform.localScale = anatomy.scale; + transform.parent = parent; + transform.localPosition = anatomy.offset; + transform.localRotation = Quaternion.identity; + sphereCollider.isTrigger = true; + sphereCollider.radius = anatomy.radius; + sensitivityLevel = anatomy.sensitivityLevel; + + if (shouldVisualizeColliders) { - Object.Destroy(renderer); + visualizer = GameObject.CreatePrimitive(PrimitiveType.Sphere).GetOrAddComponent(); + visualizer.material.color = Color.gray; + visualizer.transform.parent = transform; + visualizer.transform.localPosition = Vector3.zero; + visualizer.transform.localScale = Vector3.one * anatomy.radius * 2; } - return sphere; - } - - internal void Init(ChaControl character, int sensitivityLevel) - { - this.character = character; - this.sensitivityLevel = sensitivityLevel; } internal bool IsCharacterVisible() From 4819dce0dc5de48af83367b8f05e20e885ecad97 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 7 Jan 2024 17:31:07 +0000 Subject: [PATCH 158/252] Update VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs index 6d7db87..30718fe 100644 --- a/BetterVR/VrController.StripUpdater.cs +++ b/BetterVR/VrController.StripUpdater.cs @@ -183,7 +183,7 @@ private void UpdateStripIndicator() stripIndicator.transform.parent = isLeftHand ? BetterVRPluginHelper.leftCursorAttach : BetterVRPluginHelper.rightCursorAttach; stripIndicator.transform.localScale = Vector3.one / 256f; - stripIndicator.transform.localPosition = Vector3.back * 0.08f; + stripIndicator.transform.localPosition = Vector3.back * 0.0625f; stripIndicator.transform.localRotation = Quaternion.identity; stripIndicator.receiveShadows = false; stripIndicator.shadowCastingMode = ShadowCastingMode.Off; From d7f96059c53260ffd196d21d85e2a881c5f76dc7 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 7 Jan 2024 17:32:20 +0000 Subject: [PATCH 159/252] Update GaugeHitIndicator.cs --- BetterVR/GaugeHitIndicator.cs | 56 +++++++++++++++++------------------ 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/BetterVR/GaugeHitIndicator.cs b/BetterVR/GaugeHitIndicator.cs index f3e9ee1..c9f1c3d 100644 --- a/BetterVR/GaugeHitIndicator.cs +++ b/BetterVR/GaugeHitIndicator.cs @@ -69,29 +69,36 @@ internal void UpdateIndicators(bool isHSpeedGestureEffective) } } - UpdateIndicatorSizeAndColor(isGaugeHit); - var camera = BetterVRPluginHelper.VRCamera; var vrOrigin = BetterVRPluginHelper.VROrigin; - if (camera && vrOrigin) - { - leftHandIndicator.transform.localPosition = - leftHandIndicator.transform.parent.InverseTransformDirection(vrOrigin.transform.up) * 0.0625f; - rightHandIndicator.transform.localPosition = - rightHandIndicator.transform.parent.InverseTransformDirection(vrOrigin.transform.up) * 0.0625f; - headIndicator.transform.position = - Vector3.SmoothDamp( - headIndicator.transform.position, - camera.transform.TransformPoint(0, 0.25f, 0.75f), - ref headIndicatorVelocity, - 1f); + if (camera == null || vrOrigin == null) return; + + headIndicator.transform.position = Vector3.SmoothDamp( + headIndicator.transform.position, + camera.transform.TransformPoint(0, 0.25f, 0.75f), + ref headIndicatorVelocity, + 1f); + headIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); + var leftParent = BetterVRPluginHelper.leftControllerCenter; + var rightParent = BetterVRPluginHelper.rightControllerCenter; + var offset = vrOrigin.transform.TransformVector(Vector3.up * 0.0625f); + + if (leftParent != null) { + if (leftHandIndicator.transform.parent != leftParent) leftHandIndicator.transform.parent = leftParent; + leftHandIndicator.transform.position = leftParent.position + offset; leftHandIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); - rightHandIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); - headIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); + } + if (rightParent != null) + { + if (rightHandIndicator.transform.parent != rightParent) rightHandIndicator.transform.parent = rightParent; + rightHandIndicator.transform.position = rightParent.position + offset; + rightHandIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); } + + UpdateIndicatorSizeAndColor(isGaugeHit); } private bool IsGaugeHit() @@ -100,22 +107,17 @@ private bool IsGaugeHit() return ctrl != null && ctrl.isGaugeHit && ctrl.loopType != -1; } - private float GetFeelLevel() - { - return Singleton.Instance?.feel_f ?? 0; - } - private void UpdateIndicatorSizeAndColor(bool isGaugeHit) { - var feelLevel = GetFeelLevel(); + var feelLevel = Singleton.Instance?.feel_f ?? 0; Color color = ShouldUsePulsingColor(isGaugeHit, feelLevel) ? Color.Lerp(FINISH_COLOR, Color.white, Mathf.Abs((Time.time * 4) % 2 - 1)) : - Color.Lerp(START_COLOR, FINISH_COLOR, feelLevel); + Color.Lerp(START_COLOR, FINISH_COLOR, feelLevel * feelLevel); if (headIndicator) { - headIndicator.transform.localScale = Vector3.one * smoothGaugeHit / 32; + headIndicator.transform.localScale = Vector3.one * smoothGaugeHit * 0.02f; headIndicator.color = color; } if (leftHandIndicator) @@ -134,7 +136,7 @@ private static bool ShouldUsePulsingColor(bool isGaugeHit, float feelLevel) { if (!isGaugeHit) return false; if (feelLevel > 0.735f && feelLevel < 0.75f) return true; - return feelLevel > 0.985f; + return feelLevel > 0.97f; } private static TextMeshPro CreateIndicator(Transform cursorAttach) @@ -147,10 +149,6 @@ private static TextMeshPro CreateIndicator(Transform cursorAttach) textMesh.fontSize = 16; textMesh.color = new Color(1, 0.25f, 0.25f); textMesh.alignment = TextAlignmentOptions.Center; - // var material = textMesh.fontMaterial; - // material.renderQueue = (int) UnityEngine.Rendering.RenderQueue.Overlay; - // textMesh.fontMaterial = material; - // textMesh.sort return textMesh; } } From 7607bc279f470e6826dc4d1d771797f402d31ca2 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 7 Jan 2024 17:33:06 +0000 Subject: [PATCH 160/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 248 ++++++++++++++++++++++---------------- 1 file changed, 145 insertions(+), 103 deletions(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index f97bad9..c80d2ff 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -1,4 +1,5 @@ using HTC.UnityPlugin.Vive; +using System.Collections.Generic; using System.Reflection; using System.Text.RegularExpressions; using UnityEngine; @@ -10,6 +11,7 @@ public class HSpeedGesture : MonoBehaviour private static readonly Regex SPNKABLE_COLLIDER_NAME_MATCHER = new Regex(@"[Ll]eg|[Ss]iri"); private static readonly Regex MOUTH_MATCHER = new Regex(@"[Mm]outh"); + internal float speed { get; private set; } internal ViveRoleProperty roleProperty; internal Transform capsuleStart; internal Transform capsuleEnd; @@ -18,10 +20,10 @@ public class HSpeedGesture : MonoBehaviour internal float sensitivityMultiplier = 1; internal InteractionCollider interactingCollider { get; private set; } + // TODO: remove internal static Vector2 hitArea; - private bool isTouching; - private bool isColliderSensitive { get { return interactingCollider != null && interactingCollider.sensitivityLevel >= 2; } } + internal bool isTouching { get; private set; } private static HSpeedGestureReceiver receiver; private static FadingHaptic _leftHandHHaptic; private static FadingHaptic _rightHandHHaptic; @@ -57,6 +59,12 @@ private static FadingHaptic rightHandFadingHaptic void Awake() { if (receiver == null) receiver = new GameObject("HSpeedGestureReceiver").AddComponent(); + receiver.AddGesture(this); + } + + void OnDestroy() + { + receiver.RemoveGesture(this); } void FixedUpdate() @@ -65,14 +73,12 @@ void FixedUpdate() var hCtrl = Singleton.Instance; if (!hCtrl) return; - float speed = + speed = VivePose.GetVelocity(roleProperty).magnitude * BetterVRPlugin.HandHSpeedSensitivity.Value * sensitivityMultiplier + VivePose.GetAngularVelocity(roleProperty).magnitude * 0.0625f; isTouching = ShouldBeTouching(speed); if (!isTouching) return; - UpdateSmoothTargetSpeed(speed, hCtrl); - var hScene = Singleton.Instance?.Hscene; var anim = hScene?.GetProcBase(); @@ -81,39 +87,11 @@ void FixedUpdate() receiver.Spnk(hScene, hCtrl)) { BetterVRPlugin.Logger.LogDebug("Spnk speed: " + speed); - if (BetterVRPlugin.HapticFeedbackIntensity.Value > 0) - { - if (roleProperty == VRControllerInput.roleL) { - leftHandFadingHaptic.duration = 0.375f; - leftHandFadingHaptic.enabled = true; - } - else if (roleProperty == VRControllerInput.roleR) - { - rightHandFadingHaptic.duration = 0.375f; - rightHandFadingHaptic.enabled = true; - } - } - } - else if (isTouching && speed > 0 && BetterVRPlugin.HapticFeedbackIntensity.Value > 0) + TriggerSpnkHaptic(); + } + else if (isTouching && speed > 0) { - var amplitude = speed / 4 * BetterVRPlugin.HapticFeedbackIntensity.Value; - var frequency = hCtrl.isGaugeHit ? 120 : 35; - if (roleProperty == VRControllerInput.roleH) - { - if (!(BetterVRPluginHelper.GetLeftHand()?.GetComponentInChildren()?.isTouching ?? false)) - { - ViveInput.TriggerHapticVibration(VRControllerInput.roleL, frequency: frequency, amplitude: amplitude / 4); - } - if (!(BetterVRPluginHelper.GetRightHand()?.GetComponentInChildren()?.isTouching ?? false)) - { - ViveInput.TriggerHapticVibration(VRControllerInput.roleR, frequency: frequency, amplitude: amplitude / 4); - } - - } - else - { - ViveInput.TriggerHapticVibration(roleProperty, frequency: frequency, amplitude: amplitude); - } + TriggerTouchingHaptic(hCtrl.isGaugeHit); } } @@ -179,44 +157,45 @@ private bool ShouldBeTouching(float speed) return interactingCollider != null; } - private void UpdateSmoothTargetSpeed(float speedInput, HSceneFlagCtrl hCtrl) + private void TriggerSpnkHaptic() { - if (!isTouching) return; - - if (!isColliderSensitive && !HSpeedGestureReceiver.IsHoushi()) { - if (hCtrl.loopType > 0) - { - if (hCtrl.isGaugeHit && speedInput > 0 && speedInput < 1.75f && hitArea != null) - { - // Reward mild collider touching is fast loops by stabilizing gauge hit. - if (Random.Range(0f, 1f) < Time.fixedDeltaTime * 4) receiver.smoothTargetSpeed = Mathf.Lerp(hitArea.x, hitArea.y, 0.5f); - } - return; - } - else if (receiver.smoothTargetSpeed > HSpeedGestureReceiver.LOOP_01_DIVIDER - hCtrl.wheelActionCount) - { - // Do not let touching less sensitive parts affect speed during fast movement. - return; - } + if (BetterVRPlugin.HapticFeedbackIntensity.Value == 0) return; + if (roleProperty == VRControllerInput.roleL) + { + leftHandFadingHaptic.duration = 0.375f; + leftHandFadingHaptic.enabled = true; } + else if (roleProperty == VRControllerInput.roleR) + { + rightHandFadingHaptic.duration = 0.375f; + rightHandFadingHaptic.enabled = true; + } + } - var targetSpeed = Mathf.Clamp(speedInput - 0.125f, 0, 2f); - - if (hCtrl.loopType == 2) + private void TriggerTouchingHaptic(bool isGaugeHit) + { + if (BetterVRPlugin.HapticFeedbackIntensity.Value == 0) return; + + var amplitude = speed / 4 * BetterVRPlugin.HapticFeedbackIntensity.Value; + var frequency = isGaugeHit ? 120 : 35; + if (roleProperty != VRControllerInput.roleH) { - // Curve speed output to require faster movement. - targetSpeed *= (targetSpeed / 2); - } - else if (interactingCollider.sensitivityLevel >= 3) { - // Curve speed output to require slower movement. - targetSpeed = Mathf.Sqrt(targetSpeed * 2); + ViveInput.TriggerHapticVibration(roleProperty, frequency: frequency, amplitude: amplitude); + return; } - if (targetSpeed <= receiver.smoothTargetSpeed) return; + // HMD has no haptic, trigger haptic on the hands unless the hands are already touching. + var leftGesture = BetterVRPluginHelper.GetLeftHand()?.GetComponentInChildren(); + if (leftGesture == null || !leftGesture.isTouching) + { + ViveInput.TriggerHapticVibration(VRControllerInput.roleL, frequency: frequency, amplitude: amplitude / 4); + } - receiver.smoothTargetSpeed = Mathf.Clamp( - targetSpeed * Time.fixedDeltaTime * receiver.GetAccelerationFactor(hCtrl) + receiver.smoothTargetSpeed, - 0, targetSpeed); + var rightGesture = BetterVRPluginHelper.GetRightHand()?.GetComponentInChildren(); + if (rightGesture == null || !rightGesture.isTouching) + { + ViveInput.TriggerHapticVibration(VRControllerInput.roleR, frequency: frequency, amplitude: amplitude / 4); + } } } @@ -233,10 +212,12 @@ public class HSpeedGestureReceiver : MonoBehaviour internal const float CUSTOM_SPEED_GAUGE_RATE = 1f / 256; internal static float outputY { get; private set; } + private static FieldInfo modeCtrlField; internal float smoothTargetSpeed = 0; private GaugeHitIndicator gaugeHitIndicator; + private HashSet gestures = new HashSet(); void Awake() { @@ -245,14 +226,17 @@ void Awake() void FixedUpdate() { - bool isEffective = (smoothTargetSpeed > MIN_EFFECTIVE_SPEED); - (gaugeHitIndicator ?? (gaugeHitIndicator = new GaugeHitIndicator())).UpdateIndicators(isEffective); - var hCtrl = Singleton.Instance; if (!hCtrl) return; + UpdateSmoothTargetSpeed(hCtrl, Time.fixedDeltaTime); + + bool isEffective = (smoothTargetSpeed > MIN_EFFECTIVE_SPEED); + if (gaugeHitIndicator == null) gaugeHitIndicator = new GaugeHitIndicator(); + gaugeHitIndicator.UpdateIndicators(isEffective); + // Reduce feel increase rate for realism. - hCtrl.speedGuageRate = isEffective ? CUSTOM_SPEED_GAUGE_RATE : ORIGINAL_SPEED_GAUGE_RATE; + hCtrl.speedGuageRate = isEffective && hCtrl.feel_f < 0.75f ? CUSTOM_SPEED_GAUGE_RATE : ORIGINAL_SPEED_GAUGE_RATE; if (!isEffective) { @@ -260,8 +244,7 @@ void FixedUpdate() return; } - outputY = GetOutput(hCtrl); - smoothTargetSpeed = Mathf.Lerp(smoothTargetSpeed, IDLE_SPEED, Time.fixedDeltaTime * GetAccelerationFactor(hCtrl)); + UpdateOutput(hCtrl); if (IsAibu() && smoothTargetSpeed < LOOP_0_DEACTIVATION_THRESHOLD && hCtrl.loopType >= 0 && hCtrl.loopType <= 2) { @@ -270,23 +253,38 @@ void FixedUpdate() } if (hCtrl.isGaugeHit && hCtrl.feel_f > 0.998f && hCtrl.feel_m > 0.75f) BetterVRPluginHelper.TryFinishHSameTime(); + } - // BetterVRPlugin.Logger.LogWarning( - // "H Loop type: " + hCtrl.loopType + " current speed: " + hCtrl.speed + - // " smooth target speed: " + smoothTargetSpeed); + internal static bool IsAibu() + { + var anim = Singleton.Instance?.Hscene?.GetProcBase(); + return anim != null && anim is Aibu; + } + + internal static bool IsHoushi() + { + var anim = Singleton.Instance?.Hscene?.GetProcBase(); + return anim != null && anim is Houshi; } - internal float GetOutput(HSceneFlagCtrl hCtrl) + private void UpdateOutput(HSceneFlagCtrl hCtrl) { if (hCtrl.loopType == -1) { - // Allow starting action using hand movement in Aibu mode. - if (IsAibu() && smoothTargetSpeed > LOOP_0_ACTIVATION_THRESHOLD) return 1; - return 0; + if (IsAibu() && smoothTargetSpeed > LOOP_0_ACTIVATION_THRESHOLD) + { + // Allow starting action using hand movement in Aibu mode. + outputY = 1; + } + else + { + outputY = 0; + } + return; } float bufferRadius = hCtrl.wheelActionCount; - var clampedSpeed = smoothTargetSpeed; + var clampedSpeed = Mathf.Clamp(smoothTargetSpeed, 0, 2); if (hCtrl.speed < LOOP_01_DIVIDER) { if (clampedSpeed < LOOP_1_ACTIVATION_THRESHOLD) clampedSpeed = Mathf.Min(clampedSpeed, LOOP_01_DIVIDER - bufferRadius); @@ -296,40 +294,84 @@ internal float GetOutput(HSceneFlagCtrl hCtrl) if (clampedSpeed > LOOP_1_DEACTIVATION_THRESHOLD) clampedSpeed = Mathf.Max(clampedSpeed, LOOP_01_DIVIDER + bufferRadius); } - if (clampedSpeed >= hCtrl.speed + bufferRadius) return 1; - if (clampedSpeed <= hCtrl.speed - bufferRadius) return -1; + outputY = 0; + // if (clampedSpeed >= hCtrl.speed + bufferRadius) outputY = 1; + //if (clampedSpeed <= hCtrl.speed - bufferRadius) outputY = -1; - return 0; + hCtrl.speed = clampedSpeed; } - internal float GetAccelerationFactor(HSceneFlagCtrl ctrl) + internal bool Spnk(HScene hScene, HSceneFlagCtrl ctrl) { - // Damp the speed more when it is in gauge hit zone to avoid voice flickering. - if (ctrl.isGaugeHit) return smoothTargetSpeed <= 1 ? 0.125f : 0.125f / smoothTargetSpeed; - - // Damp the speed to delay starting Aibu. - if (ctrl.loopType == -1) return 0.375f; - - return smoothTargetSpeed <= 1 ? 1f : 1 / smoothTargetSpeed; + var anim = hScene.GetProcBase(); + if (anim == null || !(anim is Spnking)) return false; + return anim.Proc(GetModeCtrl(hScene), ctrl.nowAnimationInfo, 1); } - internal static bool IsAibu() + internal void AddGesture(HSpeedGesture gesture) { - var anim = Singleton.Instance?.Hscene?.GetProcBase(); - return anim != null && anim is Aibu; + gestures.Add(gesture); } - internal static bool IsHoushi() + internal void RemoveGesture(HSpeedGesture gesture) { - var anim = Singleton.Instance?.Hscene?.GetProcBase(); - return anim != null && anim is Houshi; + gestures.Remove(gesture); } - internal bool Spnk(HScene hScene, HSceneFlagCtrl ctrl) + private void UpdateSmoothTargetSpeed(HSceneFlagCtrl hCtrl, float deltaTime) { - var anim = hScene.GetProcBase(); - if (anim == null || !(anim is Spnking)) return false; - return anim.Proc(GetModeCtrl(hScene), ctrl.nowAnimationInfo, 1); + float targetSpeed = IDLE_SPEED; + bool hasMildTouching = false; + + foreach (var gesture in gestures) + { + if (!gesture.isTouching) continue; + + targetSpeed = Mathf.Max(targetSpeed, 0); + + if (gesture.interactingCollider.sensitivityLevel == 1) + { + if (gesture.speed > 0 && gesture.speed < 1.75f) hasMildTouching = true; + if (hCtrl.loopType > 0 || smoothTargetSpeed > HSpeedGestureReceiver.LOOP_01_DIVIDER - hCtrl.wheelActionCount) + { + // Do not let touching less sensitive parts affect speed during fast movement. + if (!IsHoushi()) continue; + } + } + + var speedInput = Mathf.Clamp(gesture.speed - 0.125f, 0, 2f); + + if (hCtrl.loopType == 2) + { + // Curve speed down to require faster movement. + speedInput *= speedInput / 2; + } + else if (gesture.interactingCollider.sensitivityLevel >= 3) + { + // Curve speed up to increase sensitivity. + speedInput = Mathf.Sqrt(speedInput * 2); + } + + targetSpeed = Mathf.Max(targetSpeed, speedInput); + } + + float accelerationFactor = 1; + if (hCtrl.isGaugeHit) { + // Damp the speed more when it is in gauge hit zone to avoid voice flickering; + // Reward mild collider touching in fast loops by stabilizing gauge hit more. + accelerationFactor = hasMildTouching && hCtrl.loopType > 0 ? 0.125f : 0.25f; + } + else if (hCtrl.loopType == -1) + { + // Damp the speed to delay starting Aibu. + accelerationFactor = 0.25f; + } + + smoothTargetSpeed = Mathf.Lerp(smoothTargetSpeed, targetSpeed, deltaTime * accelerationFactor); + + // BetterVRPlugin.Logger.LogWarning( + // "H Loop type: " + hCtrl.loopType + " current speed: " + hCtrl.speed + + // " smooth target speed: " + smoothTargetSpeed); } private static int GetModeCtrl(HScene hScene) From 9a8f99c5381c2d9f8481a688be7ac7e9b1a19dda Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 04:15:18 +0000 Subject: [PATCH 161/252] Update BetterVRPlugin.Helper.cs --- BetterVR/BetterVRPlugin.Helper.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/BetterVR/BetterVRPlugin.Helper.cs b/BetterVR/BetterVRPlugin.Helper.cs index 6c99b8b..49ef61a 100644 --- a/BetterVR/BetterVRPlugin.Helper.cs +++ b/BetterVR/BetterVRPlugin.Helper.cs @@ -73,7 +73,7 @@ internal static Transform leftControllerCenter { get { - if (CreateTransformIfNotPresent(ref _leftControllerCenter, parent: FindLeftControllerRenderModel(out var center))) + if (CreateTransformIfNotPresent(ref _leftControllerCenter, parent: FindLeftControllerRenderModel(out var center)?.parent)) { _leftControllerCenter.name = "LeftControllerCenter"; _leftControllerCenter.position = center; @@ -85,7 +85,7 @@ internal static Transform rightControllerCenter { get { - if (CreateTransformIfNotPresent(ref _rightControllerCenter, parent: FindRightControllerRenderModel(out var center))) + if (CreateTransformIfNotPresent(ref _rightControllerCenter, parent: FindRightControllerRenderModel(out var center)?.parent)) { _rightControllerCenter.name = "RightControllerCenter"; _rightControllerCenter.position = center; @@ -232,7 +232,7 @@ internal static void UpdatePlayerColliderActivity() { var player = BetterVRPlugin.GetPlayer(); if (player == null) return; - var colliders = player.objTop.GetComponentsInChildren(); + var colliders = player.objTop.GetComponentsInChildren(true); foreach (var collider in colliders) { if (HAND_NAME_MATCHER.IsMatch(collider.name)) @@ -278,7 +278,7 @@ private static void UpdatePDisplay() // Reparent so that it is a sibling instead of a child of simpleBody and // can be displayed even if simpleBody is hidden. simplePClone.transform.SetParent(simpleBody.transform.parent, worldPositionStays: true); - var renderers = simplePClone.GetComponentsInChildren(); + var renderers = simplePClone.GetComponentsInChildren(true); foreach (var renderer in renderers) { renderer.enabled = true; @@ -290,10 +290,10 @@ private static void UpdatePDisplay() simplePClone?.SetActive(shouldUseSimpleP); // Hide the original part now that there is a clone. - var tamaRenderer = simpleBodyEtc?.objDanTama?.GetComponentInChildren(); + var tamaRenderer = simpleBodyEtc?.objDanTama?.GetComponentInChildren(true); if (tamaRenderer) tamaRenderer.enabled = false; - var saoRenderer = simpleBodyEtc?.objDanSao?.GetComponentInChildren(); + var saoRenderer = simpleBodyEtc?.objDanSao?.GetComponentInChildren(true); if (saoRenderer) saoRenderer.enabled = false; var regularBodyEtc = player.cmpBody?.targetEtc; @@ -392,7 +392,7 @@ private static Transform FindControllerRenderModel(GameObject controller, out Ve Transform renderModel = controller.transform.FindLoop("Model") ?? controller.transform.FindLoop("OpenVRRenderModel"); if (!renderModel) return null; - var meshFilter = renderModel.GetComponentInChildren(); + var meshFilter = renderModel.GetComponentInChildren(true); center = meshFilter ? meshFilter.transform.TransformPoint(meshFilter.mesh.bounds.center) : controller.transform.position; @@ -403,7 +403,7 @@ private static void UpdateControllerVisibilty(Transform renderModel) { if (!renderModel) return; bool shouldShowController = !VRGlove.isShowingGloves || !BetterVRPlugin.IsHidingControllersEnabled(); - var renderers = renderModel.GetComponentsInChildren(); + var renderers = renderModel.GetComponentsInChildren(true); foreach (var renderer in renderers) renderer.enabled = shouldShowController; } @@ -434,7 +434,7 @@ void Update() var player = BetterVRPlugin.GetPlayer(); if (!player || !player.loadEnd) return; - var source = player.cmpSimpleBody?.targetEtc?.objBody?.GetComponentInChildren(); + var source = player.cmpSimpleBody?.targetEtc?.objBody?.GetComponentInChildren(true); if (!source) return; var meshRenderer = GetComponent(); From 7c7d9c76f93a503cbd6140f7b26df7fc8f2f9d70 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 04:15:58 +0000 Subject: [PATCH 162/252] Update VRController.Hooks.cs --- BetterVR/VRController.Hooks.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/BetterVR/VRController.Hooks.cs b/BetterVR/VRController.Hooks.cs index 6a18a96..7eb1a79 100644 --- a/BetterVR/VRController.Hooks.cs +++ b/BetterVR/VRController.Hooks.cs @@ -109,7 +109,6 @@ internal static void ChaControlLoadCharaFbxDataAsyncPrefix(AIChara.ChaControl __ internal static void ChaControlLoadCharaFbxDataAsyncPostfix(AIChara.ChaControl __instance) { BetterVRPluginHelper.UpdateControllersVisibilty(); - BetterVRPluginHelper.UpdatePrivacyScreen(Color.black); VRControllerCollider.UpdateDynamicBoneColliders(); } From d31a90ca94ab25ed24554ca485f2d18a80e4b809 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 04:16:34 +0000 Subject: [PATCH 163/252] Update VRGlove.cs --- BetterVR/VRGlove.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/BetterVR/VRGlove.cs b/BetterVR/VRGlove.cs index 0a1f4ca..9c56e0d 100644 --- a/BetterVR/VRGlove.cs +++ b/BetterVR/VRGlove.cs @@ -2,8 +2,6 @@ using HS2VR; using IllusionUtility.GetUtility; using UnityEngine; -using UnityEngine.UI; -using UnityEngine.Events; namespace BetterVR { @@ -50,13 +48,15 @@ void Update() if (!shouldShowHand) return; var camera = BetterVRPluginHelper.VRCamera; - if (camera && gloveRenderer.transform.parent != camera.transform) + if (camera != null && gloveRenderer.transform.parent != camera.transform) { // Parent the renderer to camera to make sure that the gloves stay in the renderer's bounds and do not get culled. gloveRenderer.transform.parent = camera.transform; gloveRenderer.transform.localPosition = Vector3.zero; - var bounds = gloveRenderer.GetComponent().bounds; - BetterVRPlugin.Logger.LogInfo("Glove renderer bounds: " + bounds); + var localBounds = gloveRenderer.localBounds; + localBounds.center = Vector3.zero; + localBounds.extents = Vector3.one * 16; + gloveRenderer.localBounds = localBounds; } if (isRepositioning) From e992690db42db04ea299e8ceab407650e23acbdc Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 04:18:40 +0000 Subject: [PATCH 164/252] Update VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 56 ++++++++++++--------------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs index 30718fe..719fc2c 100644 --- a/BetterVR/VrController.StripUpdater.cs +++ b/BetterVR/VrController.StripUpdater.cs @@ -34,8 +34,6 @@ internal StripUpdater(ViveRoleProperty handRole) internal void CheckStrip(bool enable) { - LoadClothIcons(); - if (BetterVRPluginHelper.VROrigin == null) return; Vector3 handPos = @@ -103,7 +101,7 @@ internal void CheckStrip(bool enable) canClothe = (grabbedStripCollider == null); } - private void LoadClothIcons() + private void LoadClothIconsIfNeeded() { if (finishedLoadingClothIcons || stripIndicator == null) { @@ -116,27 +114,18 @@ private void LoadClothIcons() return; } - while (clothIcons.Count < 8) - { - clothIcons.Add(null); - } + while (clothIcons.Count < 8) clothIcons.Add(null); - if (!clothIconCanvas) - { - clothIconCanvas = new GameObject("ClothIconCanvas").AddComponent(); - clothIconCanvas.transform.SetParent(stripIndicator.transform, false); - clothIconCanvas.transform.localPosition = Vector3.zero; - clothIconCanvas.transform.localRotation = Quaternion.Euler(120, 0, 0); - clothIconCanvas.transform.localScale = Vector3.one * 6; - } + if (!clothIconCanvas) clothIconCanvas = new GameObject("ClothIconCanvas").AddComponent(); + clothIconCanvas.transform.SetParent(stripIndicator.transform, false); + clothIconCanvas.transform.localPosition = Vector3.zero; + clothIconCanvas.transform.localRotation = Quaternion.Euler(120, 0, 0); + clothIconCanvas.transform.localScale = Vector3.one * 6; bool waitingForIcons = false; for (int i = 0; i < 8; i++) { - if (clothIcons[i] != null) - { - continue; - } + if (clothIcons[i] != null) continue; var allClothButtons = hSceneSprite.objCloth.objs; if (allClothButtons == null || allClothButtons.Count <= i) @@ -169,6 +158,7 @@ private void LoadClothIcons() } finishedLoadingClothIcons = !waitingForIcons; + if (finishedLoadingClothIcons) BetterVRPlugin.Logger.LogInfo("Loaded cloth icons"); } private void UpdateStripIndicator() @@ -176,12 +166,12 @@ private void UpdateStripIndicator() Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; if (vrOrigin == null) return; - if (stripIndicator == null || stripIndicator.gameObject == null) + var parent = handRole == VRControllerInput.roleL ? BetterVRPluginHelper.leftCursorAttach : BetterVRPluginHelper.rightCursorAttach; + if (parent == null) return; + if (stripIndicator == null || stripIndicator.gameObject == null || stripIndicator.transform.parent != parent) { - bool isLeftHand = handRole == VRControllerInput.roleL; stripIndicator = GameObject.CreatePrimitive(PrimitiveType.Sphere).GetComponent(); - stripIndicator.transform.parent = - isLeftHand ? BetterVRPluginHelper.leftCursorAttach : BetterVRPluginHelper.rightCursorAttach; + stripIndicator.transform.parent = parent; stripIndicator.transform.localScale = Vector3.one / 256f; stripIndicator.transform.localPosition = Vector3.back * 0.0625f; stripIndicator.transform.localRotation = Quaternion.identity; @@ -201,6 +191,8 @@ private void UpdateStripIndicator() stripIndicator.material.color = STRIP_INDICATOR_COLORS[grabbedStripCollider.clothType]; if (clothIcons == null) finishedLoadingClothIcons = false; + LoadClothIconsIfNeeded(); + if (!finishedLoadingClothIcons) return; for (int i = 0; i < clothIcons.Count; i++) { @@ -239,7 +231,7 @@ private static StripCollider FindClosestStripCollider(Vector3 position, float ra public struct ColliderAnatomy { - public ColliderAnatomy(byte clothType, Vector3? scale = null, Vector3? offset = null, float? radius = null, int sensitivityLevel = 0) + public ColliderAnatomy(int clothType, Vector3? scale = null, Vector3? offset = null, float? radius = null, int sensitivityLevel = 0) { this.clothType = clothType; this.scale = scale ?? Vector3.one; @@ -248,7 +240,7 @@ public ColliderAnatomy(byte clothType, Vector3? scale = null, Vector3? offset = this.sensitivityLevel = sensitivityLevel; } - internal byte clothType; + internal int clothType; internal Vector3 scale; internal Vector3 offset; internal float radius; @@ -264,16 +256,16 @@ public class StripColliderRegistry : MonoBehaviour { new Regex(@"Kosi01$"), new ColliderAnatomy(1, scale: Vector3.one * 1.25f) }, // Bottom { new Regex(@"Siri_[LR]$"), new ColliderAnatomy(1, scale: Vector3.one * 1.25f, null, 0.75f, sensitivityLevel: 1) }, // Bottom { new Regex(@"Belly_Mid_High"), new ColliderAnatomy(1, scale: new Vector3(1f, 0.75f, 0.5f), sensitivityLevel: 1) }, // Bottom - { new Regex(@"N_Chest$"), new ColliderAnatomy(2, scale: Vector3.one * 1.25f) }, // Top inner + { new Regex(@"N_Chest$"), new ColliderAnatomy(2, scale: new Vector3(1.5f, 1f, 1.5f), offset: Vector3.down * 1f) }, // Top inner { new Regex(@"Kokan$|agina_root$"), new ColliderAnatomy(3, sensitivityLevel: 3) }, // Under { new Regex(@"Wrist_dam_[LR]$"), new ColliderAnatomy(4, scale: Vector3.one * 0.5f) }, // Gloves { new Regex(@"LegUp01_[LR]$"), new ColliderAnatomy(5, scale: new Vector3(1.5f, 2f, 1.5f), offset: Vector3.down * 2f, sensitivityLevel: 1) }, // Pants { new Regex(@"LegLow01_[LR]$"), new ColliderAnatomy(5, scale: Vector3.one * 1.25f) }, // Pants { new Regex(@"LegLowRoll_[LR]$"), new ColliderAnatomy(6) }, // Socks { new Regex(@"Foot01_[LR]$"), new ColliderAnatomy(7) }, // Shoes - { new Regex(@"Mune_Nip01_[LR]$"), new ColliderAnatomy(8, sensitivityLevel: 2) }, // No cloth, for touching only - { new Regex(@"cf_J_Neck$"), new ColliderAnatomy(8, scale: Vector3.one * 1.25f, sensitivityLevel: 1) }, // No cloth, for touching only - { new Regex(@"N_Mouth$"), new ColliderAnatomy(8, scale: Vector3.one * 0.5f) } // No cloth, for touching only + { new Regex(@"Mune_Nip01_[LR]$"), new ColliderAnatomy(-1, sensitivityLevel: 2) }, // No cloth, for touching only + { new Regex(@"cf_J_Neck$"), new ColliderAnatomy(-1, scale: Vector3.one * 1.25f, sensitivityLevel: 1) }, // No cloth, for touching only + { new Regex(@"N_Mouth$"), new ColliderAnatomy(-1, scale: Vector3.one * 0.5f) } // No cloth, for touching only }; private bool hasAddedColliders = false; @@ -347,10 +339,10 @@ private void AddColliderInChildren(Transform transform) public class StripCollider : InteractionCollider { - public byte clothType { get; private set; } + public int clothType { get; private set; } public byte stripLevel { get { return IsValidClothType(clothType) ? character.fileStatus.clothesState[clothType] : (byte)0; } } - internal static bool IsValidClothType(byte i) { return 0 <= i && i < 8; } + internal static bool IsValidClothType(int i) { return 0 <= i && i < 8; } internal static InteractionCollider Create( ChaControl character, ColliderAnatomy anatomy, Transform parent, Transform scaleReference) @@ -373,7 +365,7 @@ internal static InteractionCollider Create( internal bool IsInteractable() { - return IsCharacterVisible() && IsValidClothType(clothType) && character.IsClothes(clothType); + return IsCharacterVisible() && IsValidClothType(clothType) && character.IsClothesStateKind(clothType); } internal bool StripMore() From 53fca4924085f9f673e3b8541779f93e13813768 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 04:19:01 +0000 Subject: [PATCH 165/252] Update VRController.Collider.cs --- BetterVR/VRController.Collider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BetterVR/VRController.Collider.cs b/BetterVR/VRController.Collider.cs index cde9466..c882d23 100644 --- a/BetterVR/VRController.Collider.cs +++ b/BetterVR/VRController.Collider.cs @@ -28,9 +28,9 @@ internal static void UpdateDynamicBoneColliders() foreach (var character in females) { if (character == null) continue; - var dynamicBones = character.GetComponentsInChildren(); + var dynamicBones = character.GetComponentsInChildren(true); foreach (var bone in dynamicBones) AddCollidersToBone(bone); - var dynamicBonesV2 = character.GetComponentsInChildren(); + var dynamicBonesV2 = character.GetComponentsInChildren(true); foreach (var bone in dynamicBonesV2) AddCollidersToBone(bone); } } From e418ccf4b1ee0ce9fa99a1e24309888883e3b256 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 04:20:46 +0000 Subject: [PATCH 166/252] Update GaugeHitIndicator.cs --- BetterVR/GaugeHitIndicator.cs | 87 ++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/BetterVR/GaugeHitIndicator.cs b/BetterVR/GaugeHitIndicator.cs index c9f1c3d..df82dc4 100644 --- a/BetterVR/GaugeHitIndicator.cs +++ b/BetterVR/GaugeHitIndicator.cs @@ -17,7 +17,7 @@ private TextMeshPro headIndicator { get { - if (!_headIndicator) _headIndicator = CreateIndicator(BetterVRPluginHelper.VROrigin?.transform); + if (!_headIndicator) _headIndicator = CreateIndicator(); return _headIndicator; } } @@ -25,7 +25,7 @@ private TextMeshPro leftHandIndicator { get { - if (!_leftHandIndicator) _leftHandIndicator = CreateIndicator(BetterVRPluginHelper.leftControllerCenter); + if (!_leftHandIndicator || _leftHandIndicator.gameObject == null) _leftHandIndicator = CreateIndicator(); return _leftHandIndicator; } } @@ -33,7 +33,7 @@ private TextMeshPro rightHandIndicator { get { - if (!_rightHandIndicator) _rightHandIndicator = CreateIndicator(BetterVRPluginHelper.rightControllerCenter); + if (!_rightHandIndicator || _rightHandIndicator.gameObject == null) _rightHandIndicator = CreateIndicator(); return _rightHandIndicator; } } @@ -74,31 +74,39 @@ internal void UpdateIndicators(bool isHSpeedGestureEffective) if (camera == null || vrOrigin == null) return; - headIndicator.transform.position = Vector3.SmoothDamp( - headIndicator.transform.position, - camera.transform.TransformPoint(0, 0.25f, 0.75f), - ref headIndicatorVelocity, - 1f); + var upDirectionInCamera = camera.transform.TransformVector( + ((Vector2) camera.transform.InverseTransformVector(vrOrigin.transform.up)).normalized); + + var targetPosition = GetHeadIndicatorTargetPosition(camera.transform, upDirectionInCamera * 0.375f); + if (smoothGaugeHit < 1 / 64f) + { + headIndicator.transform.position = targetPosition; + headIndicatorVelocity = Vector3.zero; + } + else + { + headIndicator.transform.position = Vector3.SmoothDamp( + headIndicator.transform.position, + targetPosition, + ref headIndicatorVelocity, + 1f); + } headIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); - var leftParent = BetterVRPluginHelper.leftControllerCenter; - var rightParent = BetterVRPluginHelper.rightControllerCenter; - var offset = vrOrigin.transform.TransformVector(Vector3.up * 0.0625f); + var offsetFromHand = upDirectionInCamera * 0.0625f; - if (leftParent != null) { - if (leftHandIndicator.transform.parent != leftParent) leftHandIndicator.transform.parent = leftParent; - leftHandIndicator.transform.position = leftParent.position + offset; + if (BetterVRPluginHelper.leftControllerCenter != null) { + leftHandIndicator.transform.position = BetterVRPluginHelper.leftControllerCenter.position + offsetFromHand; leftHandIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); } - if (rightParent != null) + if (BetterVRPluginHelper.rightControllerCenter != null) { - if (rightHandIndicator.transform.parent != rightParent) rightHandIndicator.transform.parent = rightParent; - rightHandIndicator.transform.position = rightParent.position + offset; + rightHandIndicator.transform.position = BetterVRPluginHelper.rightControllerCenter.position + offsetFromHand; rightHandIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); } - UpdateIndicatorSizeAndColor(isGaugeHit); + UpdateSizeAndColor(isGaugeHit); } private bool IsGaugeHit() @@ -107,7 +115,37 @@ private bool IsGaugeHit() return ctrl != null && ctrl.isGaugeHit && ctrl.loopType != -1; } - private void UpdateIndicatorSizeAndColor(bool isGaugeHit) + private Vector3 GetHeadIndicatorTargetPosition(Transform camera, Vector3 offset) + { + var characters = Singleton.Instance?.Hscene?.GetFemales(); + + // Default position of the gauge hit indicator relative to the camera. + var p = new Vector3(0, 0.25f, 1f); + + if (characters != null) + { + foreach (var character in characters) + { + if (character == null || !character.isActiveAndEnabled || !character.visibleAll) continue; + // A spot above the character's head. + var target = + camera.InverseTransformPoint(character.objHeadBone.transform.TransformPoint(Vector3.up * 0.125f) + offset); + + // If the target is too near or too far, do not use it. + if (target.z < 0.125f || target.z > 1) continue; + + // If the target is too much off the center of view, do not use it. + if (Mathf.Abs(target.x) > target.z * 0.75f || Mathf.Abs(target.y) > target.z * 0.75f) continue; + + // Snap gauge hit indicator above the character's head. + p = target; + break; + } + } + return camera.TransformPoint(p); + } + + private void UpdateSizeAndColor(bool isGaugeHit) { var feelLevel = Singleton.Instance?.feel_f ?? 0; Color color = @@ -117,7 +155,7 @@ private void UpdateIndicatorSizeAndColor(bool isGaugeHit) if (headIndicator) { - headIndicator.transform.localScale = Vector3.one * smoothGaugeHit * 0.02f; + headIndicator.transform.localScale = Vector3.one * smoothGaugeHit / 32; headIndicator.color = color; } if (leftHandIndicator) @@ -139,16 +177,19 @@ private static bool ShouldUsePulsingColor(bool isGaugeHit, float feelLevel) return feelLevel > 0.97f; } - private static TextMeshPro CreateIndicator(Transform cursorAttach) + private static TextMeshPro CreateIndicator() { - if (!cursorAttach) return null; + Transform parent = BetterVRPluginHelper.VROrigin?.transform; + if (parent == null) return null; var textMesh = new GameObject().AddComponent().gameObject.AddComponent(); - textMesh.transform.SetParent(cursorAttach); + + textMesh.transform.SetParent(parent); textMesh.text = "\u2665"; textMesh.fontSize = 16; textMesh.color = new Color(1, 0.25f, 0.25f); textMesh.alignment = TextAlignmentOptions.Center; + return textMesh; } } From e8dd93d592adce17bca879d14de0ebb3b6aa3854 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 04:22:06 +0000 Subject: [PATCH 167/252] Update AssemblyInfo.cs --- BetterVR/Properties/AssemblyInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BetterVR/Properties/AssemblyInfo.cs b/BetterVR/Properties/AssemblyInfo.cs index dd90060..6bb9d90 100644 --- a/BetterVR/Properties/AssemblyInfo.cs +++ b/BetterVR/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.InteropServices; using BetterVR; @@ -6,7 +6,7 @@ // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("BetterVR")] -[assembly: AssemblyDescription("Adds a few enhancements to VR for story mode")] +[assembly: AssemblyDescription("Adds a handful of enhancements and new motion control features to VR for story mode")] [assembly: AssemblyProduct("BetterVR")] [assembly: AssemblyCopyright("Copyright © 2019")] From d116f6190fc8a458893330822771f7e608b94d3a Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 04:26:54 +0000 Subject: [PATCH 168/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index e6c8cc0..0efdf20 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -12,7 +12,7 @@ namespace BetterVR public partial class BetterVRPlugin : BaseUnityPlugin { public const string GUID = "BetterVR"; - public const string Version = "0.47"; + public const string Version = "0.5"; internal static new ManualLogSource Logger { get; private set; } #if DEBUG @@ -120,6 +120,7 @@ private static void CheckRadialMenu(RadialMenu radialMenu, HandRole handRole) VRControllerCollider.UpdateDynamicBoneColliders(); break; case 1: + // InteractionCollider.shouldVisualizeColliders = !InteractionCollider.shouldVisualizeColliders; VRControllerCollider.UpdateDynamicBoneColliders(); break; case 2: From 33e5d2a402172b8c2b9d5ba3f40da26a2b35bf28 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 04:27:17 +0000 Subject: [PATCH 169/252] Update release.cmd --- release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.cmd b/release.cmd index 44d6339..98fbe03 100644 --- a/release.cmd +++ b/release.cmd @@ -1,7 +1,7 @@ ::Zips the dll into the correct directory structure for release ::Make sure to increment the version -set version=0.47 +set version=0.5 set name=HS2_BetterVR IF NOT EXIST "../release/%name%/BepInEx/plugins" MKDIR "../release/%name%/BepInEx/plugins" From 13e5d1a8cef520c9eb4250a67afc5089e7487d26 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 04:30:00 +0000 Subject: [PATCH 170/252] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 87bdb1e..9a514e0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Forked from thojmr/HS2_BetterVR, this plugin for `Honey Select 2 VR` fixes a han - Adds config option to allow vertical rotation. - `View reset` option in the radial menu will reset vertical rotation too - Adds a `Random` button to the Character selection screen that will select a random female/male, and start the HScene. - - You can select a map, and then hit random to use a specific map with random characters + - You can select a map, and then hit `random` in the UI or return/enter on the keyboard to use a specific map with random characters - (May not work in some cases) The config option `Multiple Heroine when Random`: will add two random heroine to the HScene - Adds radial menu with quick actions to recenter view, toggle player visibility, move onto next H stage, etc. - Long press A or X to activate radial menu @@ -37,6 +37,7 @@ Forked from thojmr/HS2_BetterVR, this plugin for `Honey Select 2 VR` fixes a han - Look for a heart icon that may show up which indicates pleasure gauge hit - Adds option to skip title scene on game start and go straight to select scene. - Adds option to unlock all positions regardless of character state. +- Adds option to tilt VR laser pointers up or down. - Fixes the bug of vanilla game not detecting thumb stick input on some platforms. - Fixes the bug of vanilla game resets camera when changing animation even if the camera initialization option is toggled off. - Fixes the non-interactable silhouette palette in game settings. From b6a9b54a56eef4e0b58028c5cdcb8f01b0187030 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 04:31:22 +0000 Subject: [PATCH 171/252] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a514e0..0b80f94 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Forked from thojmr/HS2_BetterVR, this plugin for `Honey Select 2 VR` fixes a han ## How to install Almost all plugins are installed in the same way. If there are any extra steps needed they will be added to the plugin descriptions below. 1. Make sure you have at least BepInEx 5.1 and latest BepisPlugins and KKAPI (Any BetterRepack will do). -2. Download the latest release of the plugin you want [here](https://github.com/thojmr/BetterVR/releases). +2. Download the latest release of the plugin you want [here](https://github.com/KhLTz/HS2_BetterVR/releases). 3. Extract the archive into your game directory. The file HS2_BetterVR.dll should end up in \BepInEx\plugins\ directory. 4. Check if there are no warnings on game startup, if the plugin has settings it should appear in plugin settings. From 170dbe6c83e73bac14f13141fc258133fca3d634 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 06:51:58 +0000 Subject: [PATCH 172/252] Update HandHeldToy.cs --- BetterVR/HandHeldToy.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/HandHeldToy.cs b/BetterVR/HandHeldToy.cs index 2017079..8492956 100644 --- a/BetterVR/HandHeldToy.cs +++ b/BetterVR/HandHeldToy.cs @@ -86,7 +86,7 @@ internal void CycleMode(bool isRightHand) { mode = (mode + 1) % 3; - if (mode == 1) + if (mode > 0) { // Bring the newly appeared object into range of hand. if (isRightHand) From 1ed1aab94d340ef71fe54ebc7a9eeca054208fba Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 06:52:22 +0000 Subject: [PATCH 173/252] Update HandHeldToy.cs --- BetterVR/HandHeldToy.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/HandHeldToy.cs b/BetterVR/HandHeldToy.cs index 8492956..227f430 100644 --- a/BetterVR/HandHeldToy.cs +++ b/BetterVR/HandHeldToy.cs @@ -86,7 +86,7 @@ internal void CycleMode(bool isRightHand) { mode = (mode + 1) % 3; - if (mode > 0) + if (mode != 0) { // Bring the newly appeared object into range of hand. if (isRightHand) From 3325cf15c19f8430f5d9ecc1be21b6a2ab464334 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 06:53:33 +0000 Subject: [PATCH 174/252] Update VRController.Collider.cs --- BetterVR/VRController.Collider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/VRController.Collider.cs b/BetterVR/VRController.Collider.cs index c882d23..27448c6 100644 --- a/BetterVR/VRController.Collider.cs +++ b/BetterVR/VRController.Collider.cs @@ -164,7 +164,7 @@ private static void AddCollidersToBone(Component bone) AddColliderToBone(rightControllerCollider, bone); AddColliderToBone(mouthCollider, bone); AddColliderToBone(floorCollider, bone); - AddColliderToBone(rightControllerCollider, bone); + AddColliderToBone(BetterVRPluginHelper.handHeldToy?.collider, bone); AddColliderToBone(BetterVRPluginHelper.leftGlove?.GetComponent()?.indexCollider, bone, INDEX_COLLIDING_BONE_MATCHER); AddColliderToBone(BetterVRPluginHelper.rightGlove?.GetComponent()?.indexCollider, bone, INDEX_COLLIDING_BONE_MATCHER); } From 8a7c43b013af7aa84f3d7370667692ebda1a587a Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 06:53:54 +0000 Subject: [PATCH 175/252] Update VRGlove.cs --- BetterVR/VRGlove.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/BetterVR/VRGlove.cs b/BetterVR/VRGlove.cs index 9c56e0d..9f1ca3c 100644 --- a/BetterVR/VRGlove.cs +++ b/BetterVR/VRGlove.cs @@ -217,13 +217,13 @@ void Update() ViveInput.GetPressEx(handRole, ControllerButton.PadTouch) || ViveInput.GetPressEx(handRole, ControllerButton.MenuTouch)) { - thumb.localRotation = Quaternion.Euler(0, 0, 5 * rotationFactor); - thumb.GetChild(0).localRotation = Quaternion.Euler(0, 0, 30 * rotationFactor); + thumb.localRotation = Quaternion.Euler(0, 10 * rotationFactor, 5 * rotationFactor); + thumb.GetChild(0).localRotation = Quaternion.Euler(0, 5 * rotationFactor, 30 * rotationFactor); } else { - thumb.localRotation = Quaternion.Euler(0, 0, 20 * rotationFactor); - thumb.GetChild(0).localRotation = Quaternion.Euler(0, 15 * rotationFactor, 35 * rotationFactor); + thumb.localRotation = Quaternion.Euler(0, 15 * rotationFactor, 20 * rotationFactor); + thumb.GetChild(0).localRotation = Quaternion.Euler(0, 10 * rotationFactor, 35 * rotationFactor); } } From b3eb764986197a1c925af0bd3a33f53489a58eb0 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 06:54:17 +0000 Subject: [PATCH 176/252] Update VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs index 719fc2c..508904c 100644 --- a/BetterVR/VrController.StripUpdater.cs +++ b/BetterVR/VrController.StripUpdater.cs @@ -263,7 +263,8 @@ public class StripColliderRegistry : MonoBehaviour { new Regex(@"LegLow01_[LR]$"), new ColliderAnatomy(5, scale: Vector3.one * 1.25f) }, // Pants { new Regex(@"LegLowRoll_[LR]$"), new ColliderAnatomy(6) }, // Socks { new Regex(@"Foot01_[LR]$"), new ColliderAnatomy(7) }, // Shoes - { new Regex(@"Mune_Nip01_[LR]$"), new ColliderAnatomy(-1, sensitivityLevel: 2) }, // No cloth, for touching only + { new Regex(@"Mune01_[LR]$"), new ColliderAnatomy(-1, scale: Vector3.one * 1.5f, sensitivityLevel: 2) }, // No cloth, for touching only + { new Regex(@"Mune_Nip01_[LR]$"), new ColliderAnatomy(-1, scale: Vector3.one * 0.25f, sensitivityLevel: 2) }, // No cloth, for touching only { new Regex(@"cf_J_Neck$"), new ColliderAnatomy(-1, scale: Vector3.one * 1.25f, sensitivityLevel: 1) }, // No cloth, for touching only { new Regex(@"N_Mouth$"), new ColliderAnatomy(-1, scale: Vector3.one * 0.5f) } // No cloth, for touching only }; From 13dca7026ee521e634a70ca9235eae7602ebd216 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 06:54:34 +0000 Subject: [PATCH 177/252] Update VRController.Hooks.cs --- BetterVR/VRController.Hooks.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/BetterVR/VRController.Hooks.cs b/BetterVR/VRController.Hooks.cs index 7eb1a79..428e23a 100644 --- a/BetterVR/VRController.Hooks.cs +++ b/BetterVR/VRController.Hooks.cs @@ -142,12 +142,6 @@ internal static void HSceneFinishPatchS() HSceneFinishPatch(); } - [HarmonyPostfix, HarmonyPatch(typeof(FeelHit), nameof(FeelHit.GetHitArea))] - internal static void FeelHitAreaRecorder(Vector2 __result) - { - HSpeedGesture.hitArea = __result; - } - [HarmonyPrefix, HarmonyPatch(typeof(Illusion.Component.UI.ColorPicker.Info), "SetImagePosition")] internal static void ColorPickerFix(Illusion.Component.UI.ColorPicker.Info __instance, PointerEventData cursorPos) { From 563da3ca335fde6a0c3d2e88d078a908eeb9b245 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 06:55:12 +0000 Subject: [PATCH 178/252] Update VRController.Pointer.cs --- BetterVR/VRController.Pointer.cs | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/BetterVR/VRController.Pointer.cs b/BetterVR/VRController.Pointer.cs index df410e6..2a5ab68 100644 --- a/BetterVR/VRController.Pointer.cs +++ b/BetterVR/VRController.Pointer.cs @@ -44,11 +44,8 @@ private static void GetHandAndSetAngle(BetterVRPluginHelper.VR_Hand vrHand) if (controller.transform.Find("LaserPointer") == null) return; - // LaserSync not only offsets the laser angle, but also reduces the lag of laser movement. laserSync = raycaster.GetOrAddComponent(); laserSync.source = new GameObject(raycaster.name + "_originalTransform").transform; - - // Parent the laser sync to the controller model so that its position and rotation is in sync with the controller. laserSync.source.parent = controllerCenter; laserSync.source.SetPositionAndRotation(raycaster.transform.position, raycaster.transform.rotation); @@ -58,24 +55,29 @@ private static void GetHandAndSetAngle(BetterVRPluginHelper.VR_Hand vrHand) class LaserSync : MonoBehaviour { - internal Transform source; + internal Transform source; // TODO: remove private float offsetAngle = 0; - private Quaternion rotationOffset = Quaternion.identity; void Update() { - if (source == null) return; + if (offsetAngle == BetterVRPlugin.SetVRControllerPointerAngle.Value) return; + offsetAngle = BetterVRPlugin.SetVRControllerPointerAngle.Value; - if (offsetAngle != BetterVRPlugin.SetVRControllerPointerAngle.Value) - { - offsetAngle = BetterVRPlugin.SetVRControllerPointerAngle.Value; - rotationOffset = Quaternion.Euler(-offsetAngle, 0, 0); - } + var oldAngles = transform.localRotation.eulerAngles; + + // Rotate the laser pointer to the desired angle. + transform.localRotation = Quaternion.Euler(-offsetAngle, 0, 0); - // Move the object to the desired positon and rotation relative to the controller model. - // The vanilla laser pointer stabilization is too aggressive and causes a laggy feel. - // Updating the laser direction here also reduces soem of the lag. - transform.SetPositionAndRotation(source.position, source.rotation * rotationOffset); + BetterVRPlugin.Logger.LogInfo("Updated laser pointer rotation: " + oldAngles + " -> " + transform.localRotation.eulerAngles); + + var stabilizer = gameObject.GetComponentInParent(); + if (stabilizer) + { + // The vanilla laser pointer stabilization is too aggressive and causes a laggy feel. + // Reduce the thresholds for a better balance between stability and responsiveness. + stabilizer.positionThreshold = 0; + stabilizer.rotationThreshold = 0.5f; + } } } } From 2b4c42587b54f8edd902711b072a6e0f09d05d1a Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 07:07:53 +0000 Subject: [PATCH 179/252] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b80f94..598c9d4 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Forked from thojmr/HS2_BetterVR, this plugin for `Honey Select 2 VR` fixes a han - Press either trigger to finish adjustment - Adds a hand-held toy that can be toggled on in the radial menu - Use radial menu to toggle it again to change it into silhouette mode - - When holding it, press A or X to attach to it to body (approximately using camera position) + - When holding it, press A or X to attach to it to body (approximated using camera position) - Adds feature of using hand movement to adjust H speed. - Start H animation regularly using controller pad/stick first - Move hand, mouth, or toy close to certain body parts and start moving From 87f6c30d07b44c7566c4b19ed0219a2420dd3525 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 07:09:03 +0000 Subject: [PATCH 180/252] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 598c9d4..83c3de2 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,9 @@ Forked from thojmr/HS2_BetterVR, this plugin for `Honey Select 2 VR` fixes a han - When holding it, press A or X to attach to it to body (approximated using camera position) - Adds feature of using hand movement to adjust H speed. - Start H animation regularly using controller pad/stick first + - In Aibu mode the animation can be started or stopped solely using by changin hand speed without using pad or stick - Move hand, mouth, or toy close to certain body parts and start moving - - Haptic feedback (if enabled) indicates that the this feature is in action + - Haptic feedback (if enabled) indicates that this feature is in action - Look for a heart icon that may show up which indicates pleasure gauge hit - Adds option to skip title scene on game start and go straight to select scene. - Adds option to unlock all positions regardless of character state. From 04611375b8dd3d5213e9321dbae102dde14f699b Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Mon, 8 Jan 2024 07:09:26 +0000 Subject: [PATCH 181/252] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83c3de2..9263a4d 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Forked from thojmr/HS2_BetterVR, this plugin for `Honey Select 2 VR` fixes a han - When holding it, press A or X to attach to it to body (approximated using camera position) - Adds feature of using hand movement to adjust H speed. - Start H animation regularly using controller pad/stick first - - In Aibu mode the animation can be started or stopped solely using by changin hand speed without using pad or stick + - In Aibu mode the animation can be started or stopped solely by changing hand speed without using pad or stick - Move hand, mouth, or toy close to certain body parts and start moving - Haptic feedback (if enabled) indicates that this feature is in action - Look for a heart icon that may show up which indicates pleasure gauge hit From e9fa7661418c1f103cbfc361b1ccf51015a3399b Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:52:12 +0000 Subject: [PATCH 182/252] Update VRController.Hooks.cs --- BetterVR/VRController.Hooks.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BetterVR/VRController.Hooks.cs b/BetterVR/VRController.Hooks.cs index 428e23a..08d6780 100644 --- a/BetterVR/VRController.Hooks.cs +++ b/BetterVR/VRController.Hooks.cs @@ -24,6 +24,7 @@ public static void InitHooks(Harmony harmonyInstance, BetterVRPlugin _pluginInst internal static void LaserPointer_SetLeftLaserPointerActive(ControllerManager __instance, bool value) { if (!value) return; + VRControllerInput.controllerManager = __instance; pluginInstance.StartCoroutine( VRControllerPointer.SetLaserAngleWithDelay(BetterVRPluginHelper.VR_Hand.left)); } @@ -32,6 +33,7 @@ internal static void LaserPointer_SetLeftLaserPointerActive(ControllerManager __ internal static void LaserPointer_SetRightLaserPointerActive(ControllerManager __instance, bool value) { if (!value) return; + VRControllerInput.controllerManager = __instance; pluginInstance.StartCoroutine( VRControllerPointer.SetLaserAngleWithDelay(BetterVRPluginHelper.VR_Hand.right)); } From a72ec00b942782452e02e5a18bd2cbc3e17de8b6 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:52:38 +0000 Subject: [PATCH 183/252] Update RadialMenu.cs --- BetterVR/RadialMenu.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/BetterVR/RadialMenu.cs b/BetterVR/RadialMenu.cs index 64d8c6a..a16edb5 100644 --- a/BetterVR/RadialMenu.cs +++ b/BetterVR/RadialMenu.cs @@ -47,6 +47,13 @@ void OnEnable() transform.parent = hand; transform.localPosition = Vector3.zero; transform.localRotation = Quaternion.Euler(90, 0, 0); + var camera = BetterVRPluginHelper.VRCamera?.transform; + if (camera) + { + transform.rotation = Quaternion.LookRotation( + Vector3.ProjectOnPlane(transform.position - camera.position, transform.up), + transform.up); + } transform.localScale = Vector3.one; transform.SetParent(BetterVRPluginHelper.VROrigin?.transform, worldPositionStays: true); selectedItemIndex = -1; From b573c1717aa01dc69426053772f013a13a58fae3 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:53:58 +0000 Subject: [PATCH 184/252] Update BetterVRPlugin.Helper.cs --- BetterVR/BetterVRPlugin.Helper.cs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/BetterVR/BetterVRPlugin.Helper.cs b/BetterVR/BetterVRPlugin.Helper.cs index 49ef61a..5bcd502 100644 --- a/BetterVR/BetterVRPlugin.Helper.cs +++ b/BetterVR/BetterVRPlugin.Helper.cs @@ -204,14 +204,14 @@ internal static void FixWorldScale(bool enable = true) // Moves VR camera to the player's head. internal static void ResetView() { - VRControllerInput.ClearRecordedVrOriginTransform(); + if (!VROrigin) return; - if (VROrigin) - { - // Remove any vertical rotation. - Quaternion rotation = VROrigin.transform.rotation; - VROrigin.transform.rotation = Quaternion.Euler(0, rotation.y, 0); - } + var preventInitCamera = VROrigin.GetComponent(); + if (preventInitCamera) preventInitCamera.enabled = false; + + // Remove any vertical rotation. + Quaternion rotation = VROrigin.transform.rotation; + VROrigin.transform.rotation = Quaternion.Euler(0, rotation.y, 0); recenterVR?.Invoke(); VRSettingUI.CameraInitAction?.Invoke(); @@ -337,6 +337,14 @@ internal static void UpdatePrivacyScreen(Color? color = null) if (color != null) privacyScreen.color = (Color) color; } + internal static Vector2 GetLeftHandPadStickCombinedOutput() + { + Vector2 output = ViveInput.GetPadAxisEx(HandRole.LeftHand); + output.x += ViveInput.GetAxisEx(HandRole.LeftHand, ControllerAxis.JoystickX); + output.y += ViveInput.GetAxisEx(HandRole.LeftHand, ControllerAxis.JoystickY); + return output; + } + internal static Vector2 GetRightHandPadStickCombinedOutput() { Vector2 output = ViveInput.GetPadAxisEx(HandRole.RightHand); From a2ac94154e0948aae44464964aa0f7be2f72324c Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:54:25 +0000 Subject: [PATCH 185/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index 0efdf20..e6e752f 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -72,8 +72,6 @@ internal void Update() // if (BetterVRPlugin.debugLog && Time.frameCount % 10 == 0) BetterVRPlugin.Logger.LogInfo($" SqueezeToTurn {SqueezeToTurn.Value} VRControllerInput.VROrigin {VRControllerInput.VROrigin}"); - VRControllerInput.MaybeRestoreVrOriginTransform(); - VRControllerInput.UpdateSqueezeMovement(); } From 88cc8cddf4ff4730412e01eace4e7ba18c108054 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:55:39 +0000 Subject: [PATCH 186/252] Update VRMenu.Hooks.cs --- BetterVR/VRMenu.Hooks.cs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/BetterVR/VRMenu.Hooks.cs b/BetterVR/VRMenu.Hooks.cs index c8f8875..ca558d4 100644 --- a/BetterVR/VRMenu.Hooks.cs +++ b/BetterVR/VRMenu.Hooks.cs @@ -72,12 +72,10 @@ internal static void ChangeAnimationPatch() return; } - if (Manager.Config.HData.InitCamera) - { - return; - } + if (Manager.Config.HData.InitCamera) return; - VRControllerInput.RecordVrOriginTransform(); + var preventInitCamera = BetterVRPluginHelper.VROrigin?.GetOrAddComponent(); + if (preventInitCamera) preventInitCamera.enabled = true; } [HarmonyPostfix, HarmonyPatch(typeof(HScene), nameof(HScene.ChangeAnimation))] @@ -136,6 +134,20 @@ internal static void CheckStartBasePrefix() PositionUnlockPatch(HSceneManager.HResourceTables); } + [HarmonyPostfix] + [HarmonyPatch(typeof(AIChara.ChaControl), "UpdateVisible")] + private static void UpdateVisible() + { + BetterVRPluginHelper.UpdatePrivacyScreen(Color.black); + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(OpenUICrtl), "Start")] + private static void OpenUICrtlPatch(OpenUICtrl __instance) + { + __instance.GetOrAddComponent(); + } + [HarmonyPrefix, HarmonyPatch(typeof(DynamicBone_Ver02), "Awake")] internal static void SiriBoneRadiusFix(DynamicBone_Ver02 __instance) { From 80cdc265e17e1772e06e91cdccb150b13d7b711f Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:56:15 +0000 Subject: [PATCH 187/252] Update VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs index 508904c..6e86a1a 100644 --- a/BetterVR/VrController.StripUpdater.cs +++ b/BetterVR/VrController.StripUpdater.cs @@ -287,7 +287,6 @@ void Update() AddColliderInChildren(character.transform); hasAddedColliders = true; - BetterVRPluginHelper.UpdatePrivacyScreen(Color.black); } void OnDestroy() From 6a1f196cecdc03ab26f216c9105c46242c90f97b Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:56:37 +0000 Subject: [PATCH 188/252] Update VRMenu.Random.cs --- BetterVR/VRMenu.Random.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/BetterVR/VRMenu.Random.cs b/BetterVR/VRMenu.Random.cs index b78286c..aaaf23a 100644 --- a/BetterVR/VRMenu.Random.cs +++ b/BetterVR/VRMenu.Random.cs @@ -35,6 +35,8 @@ public static void OnSelectRandomBtn() SetMales(); + BetterVRPluginHelper.UpdatePrivacyScreen(Color.white); + //Load the HScene Scene.LoadReserve(new Scene.Data { @@ -292,7 +294,7 @@ internal class StartRandomOnKeyEnter : MonoBehaviour void Update() { - if (Singleton.Instance == null || randomButton == null) return; + if (Singleton.Instance == null || Scene.IsNowLoading || randomButton == null) return; if (Input.GetKeyDown("enter") || Input.GetKeyDown("return")) { From bb03a0b244aef0c82c23cbe5e7d78df32d87281a Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:57:08 +0000 Subject: [PATCH 189/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 86 +++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index c80d2ff..49e7950 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -59,12 +59,12 @@ private static FadingHaptic rightHandFadingHaptic void Awake() { if (receiver == null) receiver = new GameObject("HSpeedGestureReceiver").AddComponent(); - receiver.AddGesture(this); + receiver.AddSourceGesture(this); } void OnDestroy() { - receiver.RemoveGesture(this); + receiver.RemoveSourceGesture(this); } void FixedUpdate() @@ -78,6 +78,7 @@ void FixedUpdate() + VivePose.GetAngularVelocity(roleProperty).magnitude * 0.0625f; isTouching = ShouldBeTouching(speed); if (!isTouching) return; + receiver.enabled = true; var hScene = Singleton.Instance?.Hscene; var anim = hScene?.GetProcBase(); @@ -91,7 +92,7 @@ void FixedUpdate() } else if (isTouching && speed > 0) { - TriggerTouchingHaptic(hCtrl.isGaugeHit); + TriggerTouchingHaptic(hCtrl); } } @@ -172,12 +173,30 @@ private void TriggerSpnkHaptic() } } - private void TriggerTouchingHaptic(bool isGaugeHit) + private void TriggerTouchingHaptic(HSceneFlagCtrl ctrl) { if (BetterVRPlugin.HapticFeedbackIntensity.Value == 0) return; - var amplitude = speed / 4 * BetterVRPlugin.HapticFeedbackIntensity.Value; - var frequency = isGaugeHit ? 120 : 35; + var amplitude = BetterVRPlugin.HapticFeedbackIntensity.Value; + if (receiver?.gaugeHitIndicator && receiver.gaugeHitIndicator.smoothGaugeHit > 0.25f) + { + // Emulate heart beats + float strength = (1 - GaugeHitIndicator.GetPulsePhase(ctrl)) % 1; + if (ctrl.feel_f >= 0.75f) + { + amplitude *= strength; + } + else + { + amplitude *= Mathf.Lerp(0.5f, 0.0625f, strength); + } + } + else + { + // Emulate touch feel + amplitude *= speed / 4; + } + var frequency = 35; if (roleProperty != VRControllerInput.roleH) { ViveInput.TriggerHapticVibration(roleProperty, frequency: frequency, amplitude: amplitude); @@ -201,9 +220,9 @@ private void TriggerTouchingHaptic(bool isGaugeHit) public class HSpeedGestureReceiver : MonoBehaviour { - internal const float IDLE_SPEED = -8f/64; - internal const float MIN_EFFECTIVE_SPEED = -7f/64; - internal const float LOOP_0_DEACTIVATION_THRESHOLD = -6f/64; + internal const float IDLE_SPEED = -8f / 64; + internal const float MIN_EFFECTIVE_SPEED = -7f / 64; + internal const float LOOP_0_DEACTIVATION_THRESHOLD = -6f / 64; internal const float LOOP_0_ACTIVATION_THRESHOLD = 0.5f; internal const float LOOP_01_DIVIDER = 1f; // This number is from the vanilla game internal const float LOOP_1_DEACTIVATION_THRESHOLD = 0.125f; @@ -216,14 +235,21 @@ public class HSpeedGestureReceiver : MonoBehaviour private static FieldInfo modeCtrlField; internal float smoothTargetSpeed = 0; - private GaugeHitIndicator gaugeHitIndicator; - private HashSet gestures = new HashSet(); + internal GaugeHitIndicator gaugeHitIndicator { get; private set; } + private HashSet sourceGestures = new HashSet(); void Awake() { modeCtrlField = typeof(HScene).GetField("modeCtrl", BindingFlags.NonPublic | BindingFlags.Instance); } + void OnDisable() + { + outputY = 0; + var ctrl = Singleton.Instance; + if (ctrl) ctrl.speedGuageRate = ORIGINAL_SPEED_GAUGE_RATE; + } + void FixedUpdate() { var hCtrl = Singleton.Instance; @@ -231,22 +257,28 @@ void FixedUpdate() UpdateSmoothTargetSpeed(hCtrl, Time.fixedDeltaTime); - bool isEffective = (smoothTargetSpeed > MIN_EFFECTIVE_SPEED); - if (gaugeHitIndicator == null) gaugeHitIndicator = new GaugeHitIndicator(); - gaugeHitIndicator.UpdateIndicators(isEffective); + if (smoothTargetSpeed < MIN_EFFECTIVE_SPEED) + { + enabled = false; + return; + } // Reduce feel increase rate for realism. - hCtrl.speedGuageRate = isEffective && hCtrl.feel_f < 0.75f ? CUSTOM_SPEED_GAUGE_RATE : ORIGINAL_SPEED_GAUGE_RATE; + hCtrl.speedGuageRate = hCtrl.feel_f < 0.75f ? CUSTOM_SPEED_GAUGE_RATE : ORIGINAL_SPEED_GAUGE_RATE; - if (!isEffective) + if (hCtrl.isGaugeHit) { - outputY = 0; - return; + if (gaugeHitIndicator == null) + { + gaugeHitIndicator = new GameObject("GaugeHitIndicator").AddComponent(); + } + gaugeHitIndicator.gameObject.SetActive(true); } UpdateOutput(hCtrl); - if (IsAibu() && smoothTargetSpeed < LOOP_0_DEACTIVATION_THRESHOLD && hCtrl.loopType >= 0 && hCtrl.loopType <= 2) + if (IsAibu() && !hCtrl.isGaugeHit && hCtrl.loopType >= 0 && hCtrl.loopType <= 2 && + smoothTargetSpeed < LOOP_0_DEACTIVATION_THRESHOLD) { // Allow stopping action with hand motion in Aibu mode. StopMotion(hCtrl); @@ -283,6 +315,11 @@ private void UpdateOutput(HSceneFlagCtrl hCtrl) return; } + outputY = 0; + + // No-turning-back point, stay in gauge hit area + if (hCtrl.feel_f > 0.965f && hCtrl.isGaugeHit) return; + float bufferRadius = hCtrl.wheelActionCount; var clampedSpeed = Mathf.Clamp(smoothTargetSpeed, 0, 2); if (hCtrl.speed < LOOP_01_DIVIDER) @@ -294,7 +331,6 @@ private void UpdateOutput(HSceneFlagCtrl hCtrl) if (clampedSpeed > LOOP_1_DEACTIVATION_THRESHOLD) clampedSpeed = Mathf.Max(clampedSpeed, LOOP_01_DIVIDER + bufferRadius); } - outputY = 0; // if (clampedSpeed >= hCtrl.speed + bufferRadius) outputY = 1; //if (clampedSpeed <= hCtrl.speed - bufferRadius) outputY = -1; @@ -308,14 +344,14 @@ internal bool Spnk(HScene hScene, HSceneFlagCtrl ctrl) return anim.Proc(GetModeCtrl(hScene), ctrl.nowAnimationInfo, 1); } - internal void AddGesture(HSpeedGesture gesture) + internal void AddSourceGesture(HSpeedGesture gesture) { - gestures.Add(gesture); + sourceGestures.Add(gesture); } - internal void RemoveGesture(HSpeedGesture gesture) + internal void RemoveSourceGesture(HSpeedGesture gesture) { - gestures.Remove(gesture); + sourceGestures.Remove(gesture); } private void UpdateSmoothTargetSpeed(HSceneFlagCtrl hCtrl, float deltaTime) @@ -323,7 +359,7 @@ private void UpdateSmoothTargetSpeed(HSceneFlagCtrl hCtrl, float deltaTime) float targetSpeed = IDLE_SPEED; bool hasMildTouching = false; - foreach (var gesture in gestures) + foreach (var gesture in sourceGestures) { if (!gesture.isTouching) continue; From de6a76e8b1d239dfbfd7cd607b73b4e640dda027 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:58:33 +0000 Subject: [PATCH 190/252] Update GaugeHitIndicator.cs --- BetterVR/GaugeHitIndicator.cs | 249 +++++++++++++++++----------------- 1 file changed, 128 insertions(+), 121 deletions(-) diff --git a/BetterVR/GaugeHitIndicator.cs b/BetterVR/GaugeHitIndicator.cs index df82dc4..3133717 100644 --- a/BetterVR/GaugeHitIndicator.cs +++ b/BetterVR/GaugeHitIndicator.cs @@ -3,194 +3,201 @@ namespace BetterVR { - internal class GaugeHitIndicator + internal class GaugeHitIndicator : MonoBehaviour { private static readonly Color START_COLOR = new Color(0.5f, 0.25f, 0.25f); - private static readonly Color FINISH_COLOR = new Color(1, 0.125f, 0.125f); - private float smoothGaugeHit = 0; - private float acceleration; - private Vector3 headIndicatorVelocity = Vector3.zero; - private TextMeshPro _headIndicator = null; - private TextMeshPro _leftHandIndicator = null; - private TextMeshPro _rightHandIndicator = null; - private TextMeshPro headIndicator + private static readonly Color FINISH_COLOR = Color.red; + private const int H_CAMERA_LAYER = 22; + + internal float smoothGaugeHit { get; private set; } = 0; + private float gaugeAcceleration; + private Vector3 velocity = Vector3.zero; + + private static Camera _gaugeCamera; + private static Camera gaugeCamera { get { - if (!_headIndicator) _headIndicator = CreateIndicator(); - return _headIndicator; + var vrCamera = BetterVRPluginHelper.VRCamera; + if (vrCamera == null) return null; + if (_gaugeCamera == null) + { + _gaugeCamera = new GameObject().AddComponent(); + _gaugeCamera.clearFlags = CameraClearFlags.Depth; + BetterVRPlugin.Logger.LogInfo("VRCamera depth: " + vrCamera.depth + " culling mask: " + vrCamera.cullingMask); + _gaugeCamera.depth = 1; + _gaugeCamera.cullingMask = 1 << H_CAMERA_LAYER; + _gaugeCamera.renderingPath = RenderingPath.VertexLit; + } + if (_gaugeCamera.transform.parent != vrCamera.transform.parent) + { + // There is some script that automaticallly moves all cameras in the scene with HMD, + // so there is no need to parent the UI camera to the VR camera itself. + _gaugeCamera.transform.parent = vrCamera.transform.parent; + _gaugeCamera.transform.position = vrCamera.transform.position; + _gaugeCamera.transform.rotation = vrCamera.transform.rotation; + _gaugeCamera.transform.localScale = vrCamera.transform.localScale; + } + return _gaugeCamera; } } - private TextMeshPro leftHandIndicator + + private TextMeshPro _heartSymbol = null; + private TextMeshPro _horizontalLines = null; + private TextMeshPro heartSymbol { - get - { - if (!_leftHandIndicator || _leftHandIndicator.gameObject == null) _leftHandIndicator = CreateIndicator(); - return _leftHandIndicator; - } + get { return _heartSymbol ?? (_heartSymbol = CreateSymbol("\u2665")); } } - private TextMeshPro rightHandIndicator + private TextMeshPro horizontalLines { - get - { - if (!_rightHandIndicator || _rightHandIndicator.gameObject == null) _rightHandIndicator = CreateIndicator(); - return _rightHandIndicator; - } + get { return _horizontalLines ?? (_horizontalLines = CreateSymbol("- -")); } } - internal void UpdateIndicators(bool isHSpeedGestureEffective) + void FixedUpdate() { - if (!leftHandIndicator || !rightHandIndicator || !headIndicator) return; + var ctrl = Singleton.Instance; + var camera = BetterVRPluginHelper.VRCamera; + var vrOrigin = BetterVRPluginHelper.VROrigin; + if (!camera || !vrOrigin || !ctrl || !heartSymbol || !horizontalLines) return; - bool isGaugeHit = IsGaugeHit(); + bool isGaugeHit = ctrl.isGaugeHit && ctrl.loopType != -1; - if (isGaugeHit && (isHSpeedGestureEffective || smoothGaugeHit > 0)) + if (transform.parent != vrOrigin.transform) { - leftHandIndicator.gameObject.SetActive(true); - rightHandIndicator.gameObject.SetActive(true); - headIndicator.gameObject.SetActive(true); - smoothGaugeHit = Mathf.SmoothDamp(smoothGaugeHit, 1, ref acceleration, 0.125f); + transform.parent = vrOrigin.transform; + transform.localScale = Vector3.one / 32; } - else if (!leftHandIndicator.isActiveAndEnabled && !rightHandIndicator.isActiveAndEnabled && !headIndicator.isActiveAndEnabled) + + if (isGaugeHit) { - return; + gaugeCamera.enabled = true; + smoothGaugeHit = Mathf.SmoothDamp(smoothGaugeHit, 1, ref gaugeAcceleration, 0.125f); } else { - smoothGaugeHit = Mathf.SmoothDamp(smoothGaugeHit, -0.125f, ref acceleration, 0.25f); + smoothGaugeHit = Mathf.SmoothDamp(smoothGaugeHit, -0.125f, ref gaugeAcceleration, 0.25f); if (smoothGaugeHit < 0) { smoothGaugeHit = 0; - acceleration = 0; - headIndicator.gameObject.SetActive(false); - leftHandIndicator.gameObject.SetActive(false); - rightHandIndicator.gameObject.SetActive(false); + gaugeAcceleration = 0; + gameObject.SetActive(false); return; } } - var camera = BetterVRPluginHelper.VRCamera; - var vrOrigin = BetterVRPluginHelper.VROrigin; - - if (camera == null || vrOrigin == null) return; - var upDirectionInCamera = camera.transform.TransformVector( ((Vector2) camera.transform.InverseTransformVector(vrOrigin.transform.up)).normalized); + var targetPosition = GetSnapPosition(camera.transform, upDirectionInCamera); + bool snappedToTarget = (targetPosition != null); - var targetPosition = GetHeadIndicatorTargetPosition(camera.transform, upDirectionInCamera * 0.375f); - if (smoothGaugeHit < 1 / 64f) - { - headIndicator.transform.position = targetPosition; - headIndicatorVelocity = Vector3.zero; - } - else + if (targetPosition == null) { - headIndicator.transform.position = Vector3.SmoothDamp( - headIndicator.transform.position, - targetPosition, - ref headIndicatorVelocity, - 1f); + targetPosition = camera.transform.TransformPoint(0f, 0, 0.5f) + 0.1875f * upDirectionInCamera; } - headIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); - var offsetFromHand = upDirectionInCamera * 0.0625f; - - if (BetterVRPluginHelper.leftControllerCenter != null) { - leftHandIndicator.transform.position = BetterVRPluginHelper.leftControllerCenter.position + offsetFromHand; - leftHandIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); + if (smoothGaugeHit > 1 / 64f) + { + transform.position = Vector3.SmoothDamp( + transform.position, (Vector3) targetPosition, ref velocity, 1f); } - - if (BetterVRPluginHelper.rightControllerCenter != null) + else { - rightHandIndicator.transform.position = BetterVRPluginHelper.rightControllerCenter.position + offsetFromHand; - rightHandIndicator.transform.LookAt(camera.transform.position, vrOrigin.transform.up); + transform.position = (Vector3)targetPosition; + velocity = Vector3.zero; } - UpdateSizeAndColor(isGaugeHit); - } + transform.LookAt(camera.transform.position, upDirectionInCamera); - private bool IsGaugeHit() - { - var ctrl = Singleton.Instance; - return ctrl != null && ctrl.isGaugeHit && ctrl.loopType != -1; + UpdateSymbols(ctrl, snappedToTarget); } - private Vector3 GetHeadIndicatorTargetPosition(Transform camera, Vector3 offset) + private Vector3? GetSnapPosition(Transform camera, Vector3 upDirection) { var characters = Singleton.Instance?.Hscene?.GetFemales(); - // Default position of the gauge hit indicator relative to the camera. - var p = new Vector3(0, 0.25f, 1f); - if (characters != null) { foreach (var character in characters) { if (character == null || !character.isActiveAndEnabled || !character.visibleAll) continue; - // A spot above the character's head. - var target = - camera.InverseTransformPoint(character.objHeadBone.transform.TransformPoint(Vector3.up * 0.125f) + offset); - - // If the target is too near or too far, do not use it. - if (target.z < 0.125f || target.z > 1) continue; - - // If the target is too much off the center of view, do not use it. - if (Mathf.Abs(target.x) > target.z * 0.75f || Mathf.Abs(target.y) > target.z * 0.75f) continue; - - // Snap gauge hit indicator above the character's head. - p = target; - break; + var head = character.objHeadBone.transform.position; + var target = head + upDirection * 0.25f; + if (isTargetInSnapRange(target, camera)) return target; } } - return camera.TransformPoint(p); + + return null; } - private void UpdateSizeAndColor(bool isGaugeHit) + private TextMeshPro CreateSymbol(string text) { - var feelLevel = Singleton.Instance?.feel_f ?? 0; + var textMesh = new GameObject().AddComponent().gameObject.AddComponent(); + textMesh.transform.SetParent(transform); + textMesh.transform.localPosition = Vector3.zero; + textMesh.transform.localRotation = Quaternion.identity; + textMesh.text = text; + textMesh.fontSize = 16; + textMesh.color = new Color(1, 0.25f, 0.25f); + textMesh.alignment = TextAlignmentOptions.Center; + textMesh.gameObject.layer = H_CAMERA_LAYER; + + textMesh.renderer.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; + textMesh.renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; + textMesh.renderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; + + return textMesh; + } + + private void UpdateSymbols(HSceneFlagCtrl ctrl, bool snappedToTarget) + { + var feelLevel = ctrl.feel_f; Color color = - ShouldUsePulsingColor(isGaugeHit, feelLevel) ? - Color.Lerp(FINISH_COLOR, Color.white, Mathf.Abs((Time.time * 4) % 2 - 1)) : + ShouldUsePulsingColor(ctrl.isGaugeHit, feelLevel) ? + Color.Lerp(FINISH_COLOR, Color.white, Mathf.Abs(GetPulsePhase(Singleton.Instance))) : Color.Lerp(START_COLOR, FINISH_COLOR, feelLevel * feelLevel); - if (headIndicator) - { - headIndicator.transform.localScale = Vector3.one * smoothGaugeHit / 32; - headIndicator.color = color; - } - if (leftHandIndicator) - { - leftHandIndicator.transform.localScale = Vector3.one * smoothGaugeHit / 64; - leftHandIndicator.color = color; - } - if (rightHandIndicator) - { - rightHandIndicator.transform.localScale = Vector3.one * smoothGaugeHit / 64; - rightHandIndicator.color = color; - } + heartSymbol.transform.localScale = Vector3.one * smoothGaugeHit; + heartSymbol.color = color; + heartSymbol.transform.localRotation = GetRotationPulse(Singleton.Instance); + + float h = horizontalLines.transform.localScale.y; + h = Mathf.Lerp(h, snappedToTarget ? -0.5f : 1.25f, Time.deltaTime * 2); + horizontalLines.transform.localScale = new Vector3(smoothGaugeHit * 5, Mathf.Clamp(h, 0, smoothGaugeHit), 1); + horizontalLines.color = color; + } + + internal static float GetPulsePhase(HSceneFlagCtrl ctrl) + { + if (ctrl == null) return 0; + if (ctrl.feel_f >= 0.96f) return (Time.time * 3.5f) % 2 - 1; + if (ctrl.feel_f >= 0.75f) return (Time.time * 2) % 2 - 1; + return (Time.time * 1.5f) % 2 - 1; } private static bool ShouldUsePulsingColor(bool isGaugeHit, float feelLevel) { if (!isGaugeHit) return false; - if (feelLevel > 0.735f && feelLevel < 0.75f) return true; + if (feelLevel > 0.74f && feelLevel < 0.75f) return true; return feelLevel > 0.97f; } - private static TextMeshPro CreateIndicator() + private static Quaternion GetRotationPulse(HSceneFlagCtrl ctrl) { - Transform parent = BetterVRPluginHelper.VROrigin?.transform; - if (parent == null) return null; - var textMesh = - new GameObject().AddComponent().gameObject.AddComponent(); - - textMesh.transform.SetParent(parent); - textMesh.text = "\u2665"; - textMesh.fontSize = 16; - textMesh.color = new Color(1, 0.25f, 0.25f); - textMesh.alignment = TextAlignmentOptions.Center; + return Quaternion.Euler(0, 0, Mathf.Lerp(-15, 15, Mathf.Abs(GetPulsePhase(ctrl)))); + } - return textMesh; + private static bool isTargetInSnapRange(Vector3 target, Transform camera) + { + var localPoint = camera.InverseTransformPoint(target); + + // If the target is too near or too far, do not snap the indicator to it. + if (localPoint.z < 0.125f || localPoint.z > 0.75f) return false; + + // If the target is too much off the center of view, do not snap the indicator to it. + if (Mathf.Abs(localPoint.x) > localPoint.z * 0.375f) return false; + if (localPoint.y < localPoint.z * (-0.5f) || localPoint.y > localPoint.z * 0.25f) return false; + + return true; } } } From 7051e846329ce320c7fe46785df570c30ab28df1 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:59:27 +0000 Subject: [PATCH 191/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index 49e7950..cb40460 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -266,7 +266,7 @@ void FixedUpdate() // Reduce feel increase rate for realism. hCtrl.speedGuageRate = hCtrl.feel_f < 0.75f ? CUSTOM_SPEED_GAUGE_RATE : ORIGINAL_SPEED_GAUGE_RATE; - if (hCtrl.isGaugeHit) + if (hCtrl.isGaugeHit && Manager.Config.HData.FeelingGauge) { if (gaugeHitIndicator == null) { From f48901463841e6721c4638e2a0cfbcddcf6fec08 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:05:23 +0000 Subject: [PATCH 192/252] Update VRMenu.Hooks.cs --- BetterVR/VRMenu.Hooks.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/VRMenu.Hooks.cs b/BetterVR/VRMenu.Hooks.cs index ca558d4..4f99b62 100644 --- a/BetterVR/VRMenu.Hooks.cs +++ b/BetterVR/VRMenu.Hooks.cs @@ -143,7 +143,7 @@ private static void UpdateVisible() [HarmonyPostfix] [HarmonyPatch(typeof(OpenUICrtl), "Start")] - private static void OpenUICrtlPatch(OpenUICtrl __instance) + private static void OpenUICrtlPatch(OpenUICrtl __instance) { __instance.GetOrAddComponent(); } From 5bef7bfda0f84c578e5205b41d16cfdb5153031c Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:06:02 +0000 Subject: [PATCH 193/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 186 +++++++++++++++++++++++++-------- 1 file changed, 140 insertions(+), 46 deletions(-) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index 643a0f9..a8f83fd 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -1,6 +1,8 @@ using TMPro; using HTC.UnityPlugin.Vive; +using Illusion.Extensions; using System; +using System.Reflection; using UnityEngine; namespace BetterVR @@ -10,9 +12,8 @@ public static class VRControllerInput internal static ViveRoleProperty roleH { get; private set; } = ViveRoleProperty.New(DeviceRole.Hmd); internal static ViveRoleProperty roleR { get; private set; } = ViveRoleProperty.New(HandRole.RightHand); internal static ViveRoleProperty roleL { get; private set; } = ViveRoleProperty.New(HandRole.LeftHand); + internal static ControllerManager controllerManager; internal static bool isDraggingScale { get { return twoHandedWorldGrab != null && twoHandedWorldGrab.canScale; } } - private static Vector3? lastVrOriginPosition; - private static Quaternion? lastVrOriginRotation; private static TwoHandedWorldGrab _twoHandedWorldGrab; private static TwoHandedWorldGrab twoHandedWorldGrab { get { @@ -43,49 +44,6 @@ internal static HandRole GetHandRole(ViveRoleProperty roleProperty) return HandRole.Invalid; } - internal static void RecordVrOriginTransform() - { - Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; - - if (vrOrigin == null) return; - - lastVrOriginPosition = vrOrigin.position; - lastVrOriginRotation = vrOrigin.rotation; - } - - internal static void ClearRecordedVrOriginTransform() - { - lastVrOriginPosition = null; - lastVrOriginRotation = null; - } - - internal static void MaybeRestoreVrOriginTransform() - { - if (Manager.Config.HData.InitCamera) - { - return; - } - - Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; - if (vrOrigin == null) return; - - if (lastVrOriginPosition != null && lastVrOriginRotation != null) - { - // Force restoring last known camera transform before animation change - // since vanilla game erroneously resets camera after changing animation - // even if the camera init option is toggled off. - vrOrigin.SetPositionAndRotation((Vector3)lastVrOriginPosition, (Quaternion)lastVrOriginRotation); - } - - // Stop attempting to restore camera transform if there is any input that might move the camera. - if (ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip) || - ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip) || - Mathf.Abs(BetterVRPluginHelper.GetRightHandPadStickCombinedOutput().x) > 0.25f || !Manager.HSceneManager.isHScene) - { - ClearRecordedVrOriginTransform(); - } - } - /// /// Handles world scaling, rotation, and locomotion when user squeezes the grip /// @@ -264,16 +222,26 @@ public class OneHandedWorldGrab : MonoBehaviour { Transform worldPivot; Transform vrOrginPlacer; + Transform stabilizer; Vector3 desiredControllerPosition; void Awake() { - (worldPivot = new GameObject().transform).parent = transform; + (worldPivot = new GameObject().transform).parent = new GameObject("RotationStabilizedController").transform; + worldPivot.parent.parent = transform; + worldPivot.parent.localPosition = Vector3.zero; + worldPivot.parent.localRotation = Quaternion.identity; (vrOrginPlacer = new GameObject().transform).parent = new GameObject().transform; } void OnEnable() { + // stabilizer = + // transform.GetComponentInParent()?.GetComponentInChildren(true)?.transform; + stabilizer = null; + + if (stabilizer) worldPivot.parent.rotation = stabilizer.rotation; + // Place the world pivot at neutral rotation. worldPivot.rotation = Quaternion.identity; // Pivot the world around the controller. @@ -284,6 +252,8 @@ void OnEnable() void OnRenderObject() { + if (stabilizer) worldPivot.parent.rotation = stabilizer.rotation; + var vrOrigin = BetterVRPluginHelper.VROrigin; if (!vrOrigin) return; @@ -311,5 +281,129 @@ void OnRenderObject() vrOrigin.transform.SetPositionAndRotation(vrOrginPlacer.position, vrOrginPlacer.rotation); } } + + public class PreventMovement : MonoBehaviour + { + private const float EXPIRATION_TIME = 16; + private Vector3 persistentPosition; + private Quaternion persitionRotation; + private float activeTime; + + void OnEnable() + { + persistentPosition = transform.position; + persitionRotation = transform.rotation; + activeTime = 0; + } + + void Update() + { + activeTime += Time.deltaTime; + + // Stop attempting to restore camera transform if there is any input that might move the camera. + if (activeTime > EXPIRATION_TIME || + ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip) || + ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip) || + Mathf.Abs(BetterVRPluginHelper.GetLeftHandPadStickCombinedOutput().x) > 0.25f || + Mathf.Abs(BetterVRPluginHelper.GetRightHandPadStickCombinedOutput().x) > 0.25f || + !Manager.HSceneManager.isHScene) + { + this.enabled = false; + return; + } + + // Force restoring last known camera transform before animation change + // since vanilla game erroneously resets camera after changing animation + // even if the camera init option is toggled off. + transform.SetPositionAndRotation(persistentPosition, persitionRotation); + } + } + + public class MenuAutoGrab : MonoBehaviour + { + private static FieldInfo cgMenuField; + private float BUTTON_PRESS_TIME_THRESHOLD = 0.5f; + private float leftButtonPressTime = 0; + private float rightButtonPressTime = 0; + private Transform hand; + private Vector3? originalScale; + private CanvasGroup menu; + internal HandRole handRole { get; private set; } = HandRole.Invalid; + + void Awake() + { + if (cgMenuField == null) cgMenuField = typeof(HS2VR.OpenUICrtl).GetField("cgMenu", BindingFlags.Instance | BindingFlags.NonPublic); + } + + void Update() + { + if (menu == null) + { + var ctrl = GetComponent(); + if (ctrl != null) menu = (CanvasGroup)cgMenuField.GetValue(ctrl); + } + + var camera = BetterVRPluginHelper.VRCamera; + + if (menu == null || camera == null) return; + + + if (ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Menu)) + { + leftButtonPressTime += Time.deltaTime; + } + else + { + leftButtonPressTime = 0; + } + + if (ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Menu)) + { + rightButtonPressTime += Time.deltaTime; + } + else + { + rightButtonPressTime = 0; + } + + + var wasHandRoleInvalid = (handRole == HandRole.Invalid); + + if (!wasHandRoleInvalid && ViveInput.GetPressDownEx(handRole, ControllerButton.Menu)) + { + if (originalScale != null) menu.transform.localScale = (Vector3)originalScale; + menu.Enable(false, true, false); + handRole = HandRole.Invalid; + return; + } + + if (leftButtonPressTime >= BUTTON_PRESS_TIME_THRESHOLD) + { + handRole = HandRole.LeftHand; + hand = BetterVRPluginHelper.leftControllerCenter; + } + else if (rightButtonPressTime >= BUTTON_PRESS_TIME_THRESHOLD) + { + handRole = HandRole.RightHand; + hand = BetterVRPluginHelper.rightControllerCenter; + } + + if (handRole == HandRole.Invalid || !hand) return; + + if (wasHandRoleInvalid) + { + menu.Enable(true, true, false); + if (originalScale == null) originalScale = menu.transform.localScale; + Vector3 newScale = hand.lossyScale / 4096f; + if (menu.transform.parent) newScale /= menu.transform.parent.lossyScale.x; + menu.transform.localScale = newScale; + controllerManager?.SetLeftLaserPointerActive(true); + controllerManager?.SetRightLaserPointerActive(true); + controllerManager?.UpdateActivity(); + } + + menu.transform.SetPositionAndRotation(hand.TransformPoint(0, 1f / 32, 3f / 16), hand.rotation * Quaternion.Euler(90, 0, 0)); + } + } } } From 57c077c2dc65df18d01c7f524a4bd02a322530ee Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:06:18 +0000 Subject: [PATCH 194/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index e6e752f..ed97fe5 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -12,7 +12,7 @@ namespace BetterVR public partial class BetterVRPlugin : BaseUnityPlugin { public const string GUID = "BetterVR"; - public const string Version = "0.5"; + public const string Version = "0.51"; internal static new ManualLogSource Logger { get; private set; } #if DEBUG From 3d5f7ee1cbc3eb12147773456e01de31cec3d901 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:06:33 +0000 Subject: [PATCH 195/252] Update release.cmd --- release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.cmd b/release.cmd index 98fbe03..8df9308 100644 --- a/release.cmd +++ b/release.cmd @@ -1,7 +1,7 @@ ::Zips the dll into the correct directory structure for release ::Make sure to increment the version -set version=0.5 +set version=0.51 set name=HS2_BetterVR IF NOT EXIST "../release/%name%/BepInEx/plugins" MKDIR "../release/%name%/BepInEx/plugins" From dbb12de2faf13b3ca98c21360d053199fa23d803 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:14:18 +0000 Subject: [PATCH 196/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index a8f83fd..a277773 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -319,6 +319,7 @@ void Update() } } + // Attaches a small menu to the hand after long pressing Y/B public class MenuAutoGrab : MonoBehaviour { private static FieldInfo cgMenuField; @@ -367,16 +368,16 @@ void Update() } - var wasHandRoleInvalid = (handRole == HandRole.Invalid); - - if (!wasHandRoleInvalid && ViveInput.GetPressDownEx(handRole, ControllerButton.Menu)) + if (handRole != HandRole.Invalid && ViveInput.GetPressDownEx(handRole, ControllerButton.Menu)) { + // Reset menu scale to vanilla size and close it. if (originalScale != null) menu.transform.localScale = (Vector3)originalScale; menu.Enable(false, true, false); handRole = HandRole.Invalid; return; } + var previousHandRole = handRole; if (leftButtonPressTime >= BUTTON_PRESS_TIME_THRESHOLD) { handRole = HandRole.LeftHand; @@ -390,18 +391,24 @@ void Update() if (handRole == HandRole.Invalid || !hand) return; - if (wasHandRoleInvalid) + if (handRole != previousHandRole) { + // Open the menu. menu.Enable(true, true, false); + + // Scale to the right size. if (originalScale == null) originalScale = menu.transform.localScale; Vector3 newScale = hand.lossyScale / 4096f; if (menu.transform.parent) newScale /= menu.transform.parent.lossyScale.x; menu.transform.localScale = newScale; + + if (controllerManager == null) controllerManager = GameObject.FindObjectOfType(); controllerManager?.SetLeftLaserPointerActive(true); controllerManager?.SetRightLaserPointerActive(true); controllerManager?.UpdateActivity(); } + // Move the menu with the hand. menu.transform.SetPositionAndRotation(hand.TransformPoint(0, 1f / 32, 3f / 16), hand.rotation * Quaternion.Euler(90, 0, 0)); } } From e537275742f0636024e26585f16d97639f1c1dfa Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:22:11 +0000 Subject: [PATCH 197/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index a277773..fbcaa3f 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -374,6 +374,10 @@ void Update() if (originalScale != null) menu.transform.localScale = (Vector3)originalScale; menu.Enable(false, true, false); handRole = HandRole.Invalid; + // Activate the laser on the menu hand so that the vanilla game will hide it upon button release; + // Hide the laser on the pointing hand directly. + controllerManager?.SetLeftLaserPointerActive(handRole == HandRole.LeftHand); + controllerManager?.SetRightLaserPointerActive(handRole == HandRole.RightHand); return; } @@ -403,6 +407,7 @@ void Update() menu.transform.localScale = newScale; if (controllerManager == null) controllerManager = GameObject.FindObjectOfType(); + // Activate both laser pointers and the vanilla game logic will hide the laser on the menu hand upon button release. controllerManager?.SetLeftLaserPointerActive(true); controllerManager?.SetRightLaserPointerActive(true); controllerManager?.UpdateActivity(); From 18e803ba26c04f32ce3d7c75381764a64257dcb5 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:32:50 +0000 Subject: [PATCH 198/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index fbcaa3f..1dfe916 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -373,11 +373,11 @@ void Update() // Reset menu scale to vanilla size and close it. if (originalScale != null) menu.transform.localScale = (Vector3)originalScale; menu.Enable(false, true, false); - handRole = HandRole.Invalid; // Activate the laser on the menu hand so that the vanilla game will hide it upon button release; // Hide the laser on the pointing hand directly. controllerManager?.SetLeftLaserPointerActive(handRole == HandRole.LeftHand); controllerManager?.SetRightLaserPointerActive(handRole == HandRole.RightHand); + handRole = HandRole.Invalid; return; } From e4d59b8541237d8730406413bdba80001a4efd27 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:23:14 +0000 Subject: [PATCH 199/252] Update VRController.Pointer.cs --- BetterVR/VRController.Pointer.cs | 46 ++++++++++---------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/BetterVR/VRController.Pointer.cs b/BetterVR/VRController.Pointer.cs index 2a5ab68..8f6f614 100644 --- a/BetterVR/VRController.Pointer.cs +++ b/BetterVR/VRController.Pointer.cs @@ -16,6 +16,12 @@ public static IEnumerator SetLaserAngleWithDelay(BetterVRPluginHelper.VR_Hand ha GetHandAndSetAngle(hand); } + public static void UpdateAngles() + { + GetHandAndSetAngle(BetterVRPluginHelper.VR_Hand.left); + GetHandAndSetAngle(BetterVRPluginHelper.VR_Hand.right); + } + /// /// Sets the angle of the laser pointer on the VR controller to the users configured value /// @@ -34,50 +40,26 @@ private static void GetHandAndSetAngle(BetterVRPluginHelper.VR_Hand vrHand) // BetterVRPluginHelper.GetRightHand()?.GetComponentInChildren(); // if (raycaster.transform.parent?.parent != controllerModel) - var laserSync = raycaster.gameObject.GetComponent(); - - // Already patched. - if (laserSync != null && laserSync.source != null && laserSync.source.parent == controllerCenter) return; - - // Leave the unpatched state available as an option in case there is some problem with the patch. - if (BetterVRPlugin.SetVRControllerPointerAngle.Value == 0) return; - - if (controller.transform.Find("LaserPointer") == null) return; + if (controller.transform.Find("LaserPointer") == null) return; - laserSync = raycaster.GetOrAddComponent(); - laserSync.source = new GameObject(raycaster.name + "_originalTransform").transform; - laserSync.source.parent = controllerCenter; - laserSync.source.SetPositionAndRotation(raycaster.transform.position, raycaster.transform.rotation); - - BetterVRPlugin.Logger.LogInfo("Laser pointer rotation offset applied"); - } - } - - class LaserSync : MonoBehaviour - { - internal Transform source; // TODO: remove - private float offsetAngle = 0; - - void Update() - { - if (offsetAngle == BetterVRPlugin.SetVRControllerPointerAngle.Value) return; - offsetAngle = BetterVRPlugin.SetVRControllerPointerAngle.Value; + var oldAngles = raycaster.transform.localRotation.eulerAngles; - var oldAngles = transform.localRotation.eulerAngles; + // Leave the unpatched state available as an option in case there is some problem with the patch. + if (BetterVRPlugin.SetVRControllerPointerAngle.Value == 0 && oldAngles.x == 0) return; // Rotate the laser pointer to the desired angle. - transform.localRotation = Quaternion.Euler(-offsetAngle, 0, 0); + raycaster.transform.localRotation = Quaternion.Euler(-BetterVRPlugin.SetVRControllerPointerAngle.Value, 0, 0); - BetterVRPlugin.Logger.LogInfo("Updated laser pointer rotation: " + oldAngles + " -> " + transform.localRotation.eulerAngles); + BetterVRPlugin.Logger.LogInfo("Updated laser pointer rotation: " + oldAngles + " -> " + raycaster.transform.localRotation.eulerAngles); - var stabilizer = gameObject.GetComponentInParent(); + var stabilizer = raycaster.GetComponentInParent(); if (stabilizer) { // The vanilla laser pointer stabilization is too aggressive and causes a laggy feel. // Reduce the thresholds for a better balance between stability and responsiveness. stabilizer.positionThreshold = 0; stabilizer.rotationThreshold = 0.5f; - } + } } } } From fd2d972a012c4cc85af78adf4a46324bd7ad5b58 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:23:40 +0000 Subject: [PATCH 200/252] Update BetterVRPlugin.Config.cs --- BetterVR/GUI/BetterVRPlugin.Config.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/BetterVR/GUI/BetterVRPlugin.Config.cs b/BetterVR/GUI/BetterVRPlugin.Config.cs index 3320b68..7d0c35f 100644 --- a/BetterVR/GUI/BetterVRPlugin.Config.cs +++ b/BetterVR/GUI/BetterVRPlugin.Config.cs @@ -96,6 +96,7 @@ public void PluginConfigInit() SetVRControllerPointerAngle = Config.Bind("VR General", "Laser Pointer Angle", -5, new ConfigDescription("0 is the default angle, and negative is down", new AcceptableValueRange(-90, 90))); + SetVRControllerPointerAngle.SettingChanged += SetVRControllerPointerAngle_SettingsChanged; FixWorldSizeScale = Config.Bind("VR General", "Fix World Scale", true, new ConfigDescription("Everything appears larger in VR, so this will shrink the worldsize down to a more realistic size.")); @@ -181,6 +182,11 @@ internal static bool IsHidingControllersEnabled() return HandDisplay.Value == "Gloves"; } + internal void SetVRControllerPointerAngle_SettingsChanged(object sender, System.EventArgs e) + { + VRControllerPointer.UpdateAngles(); + } + internal void FixWorldSizeScale_SettingsChanged(object sender, System.EventArgs e) { BetterVRPluginHelper.FixWorldScale(FixWorldSizeScale.Value); From db2f600d5e5ba282e475ea074b3db750a6b63e19 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:27:53 +0000 Subject: [PATCH 201/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 75 ++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 26 deletions(-) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index 1dfe916..6664d18 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -236,12 +236,6 @@ void Awake() void OnEnable() { - // stabilizer = - // transform.GetComponentInParent()?.GetComponentInChildren(true)?.transform; - stabilizer = null; - - if (stabilizer) worldPivot.parent.rotation = stabilizer.rotation; - // Place the world pivot at neutral rotation. worldPivot.rotation = Quaternion.identity; // Pivot the world around the controller. @@ -326,9 +320,11 @@ public class MenuAutoGrab : MonoBehaviour private float BUTTON_PRESS_TIME_THRESHOLD = 0.5f; private float leftButtonPressTime = 0; private float rightButtonPressTime = 0; - private Transform hand; + private Transform controllerCenter; private Vector3? originalScale; + private float? originalLaserWidth; private CanvasGroup menu; + private bool isInUse = false; internal HandRole handRole { get; private set; } = HandRole.Invalid; void Awake() @@ -348,7 +344,6 @@ void Update() if (menu == null || camera == null) return; - if (ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Menu)) { leftButtonPressTime += Time.deltaTime; @@ -367,16 +362,16 @@ void Update() rightButtonPressTime = 0; } - - if (handRole != HandRole.Invalid && ViveInput.GetPressDownEx(handRole, ControllerButton.Menu)) + if (isInUse && menu.alpha < 0.9f) { // Reset menu scale to vanilla size and close it. if (originalScale != null) menu.transform.localScale = (Vector3)originalScale; - menu.Enable(false, true, false); - // Activate the laser on the menu hand so that the vanilla game will hide it upon button release; - // Hide the laser on the pointing hand directly. - controllerManager?.SetLeftLaserPointerActive(handRole == HandRole.LeftHand); - controllerManager?.SetRightLaserPointerActive(handRole == HandRole.RightHand); + if (originalLaserWidth != null) SetLaserWidths((float)originalLaserWidth); + isInUse = false; + + controllerManager?.SetLeftLaserPointerActive(false); + controllerManager?.SetRightLaserPointerActive(false); + controllerManager?.UpdateActivity(); handRole = HandRole.Invalid; return; } @@ -385,15 +380,21 @@ void Update() if (leftButtonPressTime >= BUTTON_PRESS_TIME_THRESHOLD) { handRole = HandRole.LeftHand; - hand = BetterVRPluginHelper.leftControllerCenter; + controllerCenter = BetterVRPluginHelper.leftControllerCenter; } else if (rightButtonPressTime >= BUTTON_PRESS_TIME_THRESHOLD) { handRole = HandRole.RightHand; - hand = BetterVRPluginHelper.rightControllerCenter; + controllerCenter = BetterVRPluginHelper.rightControllerCenter; + } + else + { + handRole = HandRole.Invalid; } - if (handRole == HandRole.Invalid || !hand) return; + if (handRole == HandRole.Invalid || !controllerCenter) return; + + isInUse = true; if (handRole != previousHandRole) { @@ -402,19 +403,41 @@ void Update() // Scale to the right size. if (originalScale == null) originalScale = menu.transform.localScale; - Vector3 newScale = hand.lossyScale / 4096f; - if (menu.transform.parent) newScale /= menu.transform.parent.lossyScale.x; - menu.transform.localScale = newScale; + Vector3 newScale = controllerCenter.lossyScale / 4096f; + menu.transform.localScale = + menu.transform.parent == null ? newScale : newScale / menu.transform.parent.lossyScale.x; + + SetLaserWidths(BetterVRPlugin.PlayerScale / 2f); if (controllerManager == null) controllerManager = GameObject.FindObjectOfType(); - // Activate both laser pointers and the vanilla game logic will hide the laser on the menu hand upon button release. - controllerManager?.SetLeftLaserPointerActive(true); - controllerManager?.SetRightLaserPointerActive(true); + // Hide the laser on the laser hand and show the laser on the other hand. + controllerManager?.SetLeftLaserPointerActive(handRole != HandRole.LeftHand); + controllerManager?.SetRightLaserPointerActive(handRole != HandRole.RightHand); controllerManager?.UpdateActivity(); } - // Move the menu with the hand. - menu.transform.SetPositionAndRotation(hand.TransformPoint(0, 1f / 32, 3f / 16), hand.rotation * Quaternion.Euler(90, 0, 0)); + if (ViveInput.GetPressEx(handRole, ControllerButton.Menu)) + { + // Move the menu with the hand. + menu.transform.SetPositionAndRotation( + controllerCenter.TransformPoint(0, 1f / 32, 3f / 16), + controllerCenter.rotation * Quaternion.Euler(90, 0, 0)); + } + } + + private void SetLaserWidths(float width) + { + SetLaserWidth(BetterVRPluginHelper.GetLeftHand(), (float) width); + SetLaserWidth(BetterVRPluginHelper.GetRightHand(), (float) width); + } + + private void SetLaserWidth(GameObject hand, float width) + { + if (hand == null) return; + var lineRenderer = hand.transform.Find("LaserPointer")?.GetComponentInChildren(true); + if (lineRenderer == null) return; + if (originalLaserWidth == null) originalLaserWidth = lineRenderer.widthMultiplier; + lineRenderer.widthMultiplier = width; } } } From 80ce2e367240605fc93f4b5acc21a76f18cf1937 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:28:21 +0000 Subject: [PATCH 202/252] Update VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs index 6e86a1a..5d50002 100644 --- a/BetterVR/VrController.StripUpdater.cs +++ b/BetterVR/VrController.StripUpdater.cs @@ -11,6 +11,7 @@ namespace BetterVR public class StripUpdater { + internal const int H_CAMERA_LAYER = 22; internal static readonly Color[] STRIP_INDICATOR_COLORS = new Color[] { Color.blue, Color.red, Color.cyan, Color.magenta, Color.yellow, Color.green, Color.white, Color.black }; @@ -210,7 +211,7 @@ private void UpdateStripIndicator() private static StripCollider FindClosestStripCollider(Vector3 position, float range, byte minStripLevel = 0, byte maxStripLevel = 2) { - Collider[] colliders = Physics.OverlapSphere(position, range); + Collider[] colliders = Physics.OverlapSphere(position, range, 1 << H_CAMERA_LAYER); StripCollider closestStripCollider = null; float closestDistance = Mathf.Infinity; foreach (Collider collider in colliders) @@ -353,6 +354,7 @@ internal static InteractionCollider Create( { var collider = gameObject.AddComponent(); collider.Init(character, anatomy, parent, scaleReference); + collider.gameObject.layer = StripUpdater.H_CAMERA_LAYER; return collider; } @@ -360,6 +362,7 @@ internal static InteractionCollider Create( stripCollider.Init(character, anatomy, parent, scaleReference); stripCollider.clothType = anatomy.clothType; stripCollider.color = StripUpdater.STRIP_INDICATOR_COLORS[anatomy.clothType]; + stripCollider.gameObject.layer = StripUpdater.H_CAMERA_LAYER; return stripCollider; } @@ -402,6 +405,7 @@ public class InteractionCollider : MonoBehaviour void Awake() { sphereCollider = gameObject.GetOrAddComponent(); + sphereCollider.gameObject.layer = StripUpdater.H_CAMERA_LAYER; } internal void Init(ChaControl character, ColliderAnatomy anatomy, Transform parent, Transform scaleReference) { From fe43e9a20c8fe49ac9105597998be7cf4abddbd2 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:28:54 +0000 Subject: [PATCH 203/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index cb40460..d4334b1 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -131,7 +131,7 @@ private bool ShouldBeTouching(float speed) } // Look for possible interacting colliders - Collider[] colliders = Physics.OverlapCapsule(capsuleStart.position, capsuleEnd.position, activationRadius * scale); + Collider[] colliders = Physics.OverlapCapsule(capsuleStart.position, capsuleEnd.position, activationRadius * scale, layerMask: 1 << StripUpdater.H_CAMERA_LAYER); foreach (var collider in colliders) { var interactionCollider = collider.GetComponent(); From 2d14c8ceab3169678cb9566d1cdbe623c57692a8 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:29:48 +0000 Subject: [PATCH 204/252] Update release.cmd --- release.cmd | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/release.cmd b/release.cmd index 8df9308..24b94b4 100644 --- a/release.cmd +++ b/release.cmd @@ -4,9 +4,10 @@ set version=0.51 set name=HS2_BetterVR -IF NOT EXIST "../release/%name%/BepInEx/plugins" MKDIR "../release/%name%/BepInEx/plugins" +IF NOT EXIST "../releases/%name%/BepInEx/plugins" MKDIR "../releases/%name%/BepInEx/plugins" COPY "../bin/%name%/BepinEx/plugins\%name%.dll" "../release/%name%/BepInEx/plugins" -"%ProgramFiles%\7-Zip\7z.exe" a -tzip "%HOMEPATH%/downloads/%name% v%version%.zip" "../release/%name%" -mx0 -start %HOMEPATH%/downloads +IF EXIST "%ProgramFiles%\7-Zip\7z.exe" "%ProgramFiles%\7-Zip\7z.exe" a -tzip "../releases/%name% v%version%.zip" "../releases/%name%" -mx0 +IF EXIST "C:\Program Files\7-Zip\7z.exe" "C:\Program Files\7-Zip\7z.exe" a -tzip "../releases/%name% v%version%.zip" "../releases/%name%" -mx0 +start .\..\releases From c2387c66529ac253ed2eb0febba0457a6d7ee0e8 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:00:18 +0000 Subject: [PATCH 205/252] Update VRController.Pointer.cs --- BetterVR/VRController.Pointer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/BetterVR/VRController.Pointer.cs b/BetterVR/VRController.Pointer.cs index 8f6f614..6cc51b3 100644 --- a/BetterVR/VRController.Pointer.cs +++ b/BetterVR/VRController.Pointer.cs @@ -1,6 +1,5 @@ using UnityEngine; using System.Collections; -using System.Reflection; namespace BetterVR { @@ -45,7 +44,7 @@ private static void GetHandAndSetAngle(BetterVRPluginHelper.VR_Hand vrHand) var oldAngles = raycaster.transform.localRotation.eulerAngles; // Leave the unpatched state available as an option in case there is some problem with the patch. - if (BetterVRPlugin.SetVRControllerPointerAngle.Value == 0 && oldAngles.x == 0) return; + if (-BetterVRPlugin.SetVRControllerPointerAngle.Value == oldAngles.x) return; // Rotate the laser pointer to the desired angle. raycaster.transform.localRotation = Quaternion.Euler(-BetterVRPlugin.SetVRControllerPointerAngle.Value, 0, 0); From d631657c5f9e1f8353f71532707e89fe3528cd59 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:05:28 +0000 Subject: [PATCH 206/252] Update VRController.Pointer.cs --- BetterVR/VRController.Pointer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/VRController.Pointer.cs b/BetterVR/VRController.Pointer.cs index 6cc51b3..7b26e5f 100644 --- a/BetterVR/VRController.Pointer.cs +++ b/BetterVR/VRController.Pointer.cs @@ -33,7 +33,7 @@ private static void GetHandAndSetAngle(BetterVRPluginHelper.VR_Hand vrHand) BetterVRPluginHelper.rightControllerCenter; if (controller == null || controllerCenter == null) return; - var raycaster = controller.GetComponentInChildren(); + var raycaster = controller.GetComponentInChildren(true); if (raycaster == null) return; // BetterVRPluginHelper.GetRightHand()?.GetComponentInChildren(); From a0adf4fa351b124497790c0fc7174435fbc59aec Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:09:58 +0000 Subject: [PATCH 207/252] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9263a4d..8867569 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,9 @@ Forked from thojmr/HS2_BetterVR, this plugin for `Honey Select 2 VR` fixes a han - Long press A or X to activate radial menu - Move hand to select quick actions - Press trigger or close radial menu to perform quick actions +- Adds feature that attaches a small in-game GUI menu to the hand + - Long press B/Y to activate the menu and attach it to hand + - Release B/Y to plce the menu in the air - Adds feature of using hand movement to dress/undress. - Press down trigger close to cloth, hold trigger and drag away to undress - Press down trigger some distance away from character, hold trigger and drag onto character to dress @@ -35,7 +38,8 @@ Forked from thojmr/HS2_BetterVR, this plugin for `Honey Select 2 VR` fixes a han - In Aibu mode the animation can be started or stopped solely by changing hand speed without using pad or stick - Move hand, mouth, or toy close to certain body parts and start moving - Haptic feedback (if enabled) indicates that this feature is in action - - Look for a heart icon that may show up which indicates pleasure gauge hit + - When the haptic feedback feels like a heart beat, it means the pleasurr gauge is hit + - Also look for a heart icon that may show up which indicates pleasure gauge hit - Adds option to skip title scene on game start and go straight to select scene. - Adds option to unlock all positions regardless of character state. - Adds option to tilt VR laser pointers up or down. From b38da9d6df7ab0a2679fb48715413ec83f31b260 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:17:54 +0000 Subject: [PATCH 208/252] Update GaugeHitIndicator.cs --- BetterVR/GaugeHitIndicator.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/BetterVR/GaugeHitIndicator.cs b/BetterVR/GaugeHitIndicator.cs index 3133717..4bbf1ea 100644 --- a/BetterVR/GaugeHitIndicator.cs +++ b/BetterVR/GaugeHitIndicator.cs @@ -159,11 +159,14 @@ private void UpdateSymbols(HSceneFlagCtrl ctrl, bool snappedToTarget) heartSymbol.transform.localScale = Vector3.one * smoothGaugeHit; heartSymbol.color = color; heartSymbol.transform.localRotation = GetRotationPulse(Singleton.Instance); + heartSymbol.gameObject.SetActive(Manager.Config.HData.FeelingGauge); float h = horizontalLines.transform.localScale.y; h = Mathf.Lerp(h, snappedToTarget ? -0.5f : 1.25f, Time.deltaTime * 2); horizontalLines.transform.localScale = new Vector3(smoothGaugeHit * 5, Mathf.Clamp(h, 0, smoothGaugeHit), 1); horizontalLines.color = color; + horizontalLines.gameObject.SetActive(Manager.Config.HData.FeelingGauge); + } internal static float GetPulsePhase(HSceneFlagCtrl ctrl) From b159140e09f4be49601497c46b423f0872bf2fa9 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:18:13 +0000 Subject: [PATCH 209/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index d4334b1..dc7f00c 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -266,7 +266,7 @@ void FixedUpdate() // Reduce feel increase rate for realism. hCtrl.speedGuageRate = hCtrl.feel_f < 0.75f ? CUSTOM_SPEED_GAUGE_RATE : ORIGINAL_SPEED_GAUGE_RATE; - if (hCtrl.isGaugeHit && Manager.Config.HData.FeelingGauge) + if (hCtrl.isGaugeHit) { if (gaugeHitIndicator == null) { From c4b8e9562aecf5f1afda9e5815751944a94c2e13 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 2 Feb 2024 02:42:26 +0000 Subject: [PATCH 210/252] Update release.cmd --- release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.cmd b/release.cmd index 24b94b4..5fc9b45 100644 --- a/release.cmd +++ b/release.cmd @@ -5,7 +5,7 @@ set version=0.51 set name=HS2_BetterVR IF NOT EXIST "../releases/%name%/BepInEx/plugins" MKDIR "../releases/%name%/BepInEx/plugins" -COPY "../bin/%name%/BepinEx/plugins\%name%.dll" "../release/%name%/BepInEx/plugins" +COPY "../bin/%name%/BepinEx/plugins\%name%.dll" "../releases/%name%/BepInEx/plugins" IF EXIST "%ProgramFiles%\7-Zip\7z.exe" "%ProgramFiles%\7-Zip\7z.exe" a -tzip "../releases/%name% v%version%.zip" "../releases/%name%" -mx0 IF EXIST "C:\Program Files\7-Zip\7z.exe" "C:\Program Files\7-Zip\7z.exe" a -tzip "../releases/%name% v%version%.zip" "../releases/%name%" -mx0 From 6dd07724252a9a4922850d1551dd9f45ae694507 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 2 Feb 2024 02:42:40 +0000 Subject: [PATCH 211/252] Update release.cmd --- release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.cmd b/release.cmd index 5fc9b45..5e29c5d 100644 --- a/release.cmd +++ b/release.cmd @@ -1,7 +1,7 @@ ::Zips the dll into the correct directory structure for release ::Make sure to increment the version -set version=0.51 +set version=0.52 set name=HS2_BetterVR IF NOT EXIST "../releases/%name%/BepInEx/plugins" MKDIR "../releases/%name%/BepInEx/plugins" From c7d27e2b7ed68325fb24eca63576398e60f1d75c Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 2 Feb 2024 02:43:32 +0000 Subject: [PATCH 212/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index ed97fe5..bc826b2 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -12,7 +12,7 @@ namespace BetterVR public partial class BetterVRPlugin : BaseUnityPlugin { public const string GUID = "BetterVR"; - public const string Version = "0.51"; + public const string Version = "0.52"; internal static new ManualLogSource Logger { get; private set; } #if DEBUG From 0899ef4eb0f3a8b4ba2837e22048779c9657ffb3 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 3 Mar 2024 00:21:26 +0000 Subject: [PATCH 213/252] Support finish H action in more modes --- BetterVR/BetterVRPlugin.Helper.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/BetterVR/BetterVRPlugin.Helper.cs b/BetterVR/BetterVRPlugin.Helper.cs index 5bcd502..552bac9 100644 --- a/BetterVR/BetterVRPlugin.Helper.cs +++ b/BetterVR/BetterVRPlugin.Helper.cs @@ -314,12 +314,20 @@ internal static void FinishH() internal static bool TryFinishHSameTime() { - var fCtrl = Singleton.Instance; + var hCtrl = Singleton.Instance; var sprite = Singleton.Instance; var anim = Singleton.Instance?.Hscene?.GetProcBase(); - if (!fCtrl || !sprite || anim == null || fCtrl.loopType < 2) return false; - if (anim is Aibu || anim is Houshi || anim is Spnking || anim is Masturbation || anim is Peeping || anim is Les) return false; + if (!hCtrl || !sprite || anim == null || hCtrl.loopType < 2) return false; + if (anim is Houshi || anim is Spnking || anim is Peeping) return false; + if (anim is Aibu || anim is Masturbation || anim is Les) + { + // No finish button available on the UI, simply set feel to gauge to full + hCtrl.feel_f = 1; + return true; + } + + if (hCtrl.feel_m < 0.75f) return false; sprite.OnClickFinishSame(); return true; From 94ec145f33ad53e1c324c14d58431702186cbe16 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 3 Mar 2024 00:22:19 +0000 Subject: [PATCH 214/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index bc826b2..ce0bb50 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -12,7 +12,7 @@ namespace BetterVR public partial class BetterVRPlugin : BaseUnityPlugin { public const string GUID = "BetterVR"; - public const string Version = "0.52"; + public const string Version = "0.53"; internal static new ManualLogSource Logger { get; private set; } #if DEBUG From 549ba99d65984954a81a88ff62141f7c20e97336 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 3 Mar 2024 00:22:34 +0000 Subject: [PATCH 215/252] Update release.cmd --- release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.cmd b/release.cmd index 5e29c5d..14af5ea 100644 --- a/release.cmd +++ b/release.cmd @@ -1,7 +1,7 @@ ::Zips the dll into the correct directory structure for release ::Make sure to increment the version -set version=0.52 +set version=0.53 set name=HS2_BetterVR IF NOT EXIST "../releases/%name%/BepInEx/plugins" MKDIR "../releases/%name%/BepInEx/plugins" From e6817b61ef8877eabe7c4e9cd40770a0e3f0edde Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 7 Mar 2024 05:10:48 +0000 Subject: [PATCH 216/252] Update release.cmd --- release.cmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release.cmd b/release.cmd index 14af5ea..bcca202 100644 --- a/release.cmd +++ b/release.cmd @@ -7,7 +7,7 @@ set name=HS2_BetterVR IF NOT EXIST "../releases/%name%/BepInEx/plugins" MKDIR "../releases/%name%/BepInEx/plugins" COPY "../bin/%name%/BepinEx/plugins\%name%.dll" "../releases/%name%/BepInEx/plugins" -IF EXIST "%ProgramFiles%\7-Zip\7z.exe" "%ProgramFiles%\7-Zip\7z.exe" a -tzip "../releases/%name% v%version%.zip" "../releases/%name%" -mx0 -IF EXIST "C:\Program Files\7-Zip\7z.exe" "C:\Program Files\7-Zip\7z.exe" a -tzip "../releases/%name% v%version%.zip" "../releases/%name%" -mx0 +IF EXIST "%ProgramFiles%\7-Zip\7z.exe" "%ProgramFiles%\7-Zip\7z.exe" a -tzip "../releases/%name%.v%version%.zip" "../releases/%name%" -mx0 +IF EXIST "C:\Program Files\7-Zip\7z.exe" "C:\Program Files\7-Zip\7z.exe" a -tzip "../releases/%name%.v%version%.zip" "../releases/%name%" -mx0 start .\..\releases From b9090f2b4804a2d21a6e265c0e6acbe5acf1b93c Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 9 May 2024 14:14:24 +0000 Subject: [PATCH 217/252] Update BetterVRPlugin.Config.cs --- BetterVR/GUI/BetterVRPlugin.Config.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/BetterVR/GUI/BetterVRPlugin.Config.cs b/BetterVR/GUI/BetterVRPlugin.Config.cs index 7d0c35f..3de855b 100644 --- a/BetterVR/GUI/BetterVRPlugin.Config.cs +++ b/BetterVR/GUI/BetterVRPlugin.Config.cs @@ -31,6 +31,8 @@ public partial class BetterVRPlugin public static ConfigEntry RightGloveRotation { get; private set; } public static ConfigEntry GloveScale { get; private set; } + public static ConfigEntry UseFingerTrackingGestures { get; private set; } + public static float PlayerScale { get { return Mathf.Pow(2, PlayerLogScale.Value); } set { PlayerLogScale.Value = Mathf.Log(value, 2); } @@ -150,6 +152,8 @@ public void PluginConfigInit() "VR General", "Hand Scale", 0.14f, new ConfigDescription("Scale of the VR gloves", new AcceptableValueRange(0.01f, 2f))); + UseFingerTrackingGestures = Config.Bind( + "VR General", "Use hand tracking gestures", false, new ConfigDescription("Use advanced finger tracking gestures")); } internal static bool IsTwoHandedTurnEnabled() From a2b7127a2d4b9ae9fdb133e02bbccf8ba00b55d1 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 9 May 2024 14:17:08 +0000 Subject: [PATCH 218/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index ce0bb50..4bb8dda 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -3,6 +3,8 @@ using Manager; using HTC.UnityPlugin.Vive; using HarmonyLib; +using System.Collections.Generic; +using System.Reflection; using UnityEngine; namespace BetterVR @@ -24,6 +26,9 @@ public partial class BetterVRPlugin : BaseUnityPlugin private static StripUpdater leftHandStripUpdater; private static StripUpdater rightsHandStripUpdater; + internal static float ILUTimer { get; private set; } = 0; + internal static bool ILUCooldown { get; private set; } = false; + internal void Start() { Logger = base.Logger; @@ -73,6 +78,21 @@ internal void Update() // if (BetterVRPlugin.debugLog && Time.frameCount % 10 == 0) BetterVRPlugin.Logger.LogInfo($" SqueezeToTurn {SqueezeToTurn.Value} VRControllerInput.VROrigin {VRControllerInput.VROrigin}"); VRControllerInput.UpdateSqueezeMovement(); + + if (VRControllerInput.IsILUGesture(HandRole.LeftHand) || VRControllerInput.IsILUGesture(HandRole.RightHand)) + { + ILUTimer += Time.deltaTime; + if (!ILUCooldown && ILUTimer > 3f) + { + BetterVRPluginHelper.FinishH(); + ILUCooldown = true; + } + } + else + { + ILUTimer = 0; + ILUCooldown = false; + } } internal static AIChara.ChaControl GetPlayer() @@ -82,9 +102,15 @@ internal static AIChara.ChaControl GetPlayer() private static void CheckRadialMenu(RadialMenu radialMenu, HandRole handRole) { - bool menuShouldBeActive = - ViveInput.GetPressDownEx(handRole, ControllerButton.AKey) || - (radialMenu.isActiveAndEnabled && ViveInput.GetPressEx(handRole, ControllerButton.AKey)); + bool shouldActivateMenu = + VRControllerInput.IsChillGesture(handRole) || + ViveInput.GetPressDownEx(handRole, ControllerButton.AKey); + + bool shouldKeepMenuActivated = + (VRControllerInput.inHandTrackingMode && ViveInput.GetPressEx(handRole, ControllerButton.Grip)) || + ViveInput.GetPressEx(handRole, ControllerButton.AKey); + + bool menuShouldBeActive = shouldActivateMenu || (shouldKeepMenuActivated && radialMenu.isActiveAndEnabled); if (menuShouldBeActive && !radialMenu.gameObject.activeSelf) { radialMenu.gameObject.SetActive(true); From 844e2c52e56fd1cffbb17af3a068d5753f417811 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 9 May 2024 14:19:40 +0000 Subject: [PATCH 219/252] Update GaugeHitIndicator.cs --- BetterVR/GaugeHitIndicator.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/BetterVR/GaugeHitIndicator.cs b/BetterVR/GaugeHitIndicator.cs index 4bbf1ea..1ff3b31 100644 --- a/BetterVR/GaugeHitIndicator.cs +++ b/BetterVR/GaugeHitIndicator.cs @@ -68,7 +68,7 @@ void FixedUpdate() transform.localScale = Vector3.one / 32; } - if (isGaugeHit) + if (isGaugeHit || (BetterVRPlugin.ILUTimer > 0 && !BetterVRPlugin.ILUCooldown)) { gaugeCamera.enabled = true; smoothGaugeHit = Mathf.SmoothDamp(smoothGaugeHit, 1, ref gaugeAcceleration, 0.125f); @@ -179,6 +179,11 @@ internal static float GetPulsePhase(HSceneFlagCtrl ctrl) private static bool ShouldUsePulsingColor(bool isGaugeHit, float feelLevel) { + if (VRControllerInput.IsILUGesture()) + { + return true; + } + if (!isGaugeHit) return false; if (feelLevel > 0.74f && feelLevel < 0.75f) return true; return feelLevel > 0.97f; From 0bbc9555acc629b6bce5716dac73610de5195589 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 9 May 2024 14:22:04 +0000 Subject: [PATCH 220/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index dc7f00c..fbd4845 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -266,7 +266,7 @@ void FixedUpdate() // Reduce feel increase rate for realism. hCtrl.speedGuageRate = hCtrl.feel_f < 0.75f ? CUSTOM_SPEED_GAUGE_RATE : ORIGINAL_SPEED_GAUGE_RATE; - if (hCtrl.isGaugeHit) + if (hCtrl.isGaugeHit || (BetterVRPlugin.ILUTimer > 0 && !BetterVRPlugin.ILUCooldown)) { if (gaugeHitIndicator == null) { @@ -303,9 +303,8 @@ private void UpdateOutput(HSceneFlagCtrl hCtrl) { if (hCtrl.loopType == -1) { - if (IsAibu() && smoothTargetSpeed > LOOP_0_ACTIVATION_THRESHOLD) + if (AllowStartingHWithGesture()) { - // Allow starting action using hand movement in Aibu mode. outputY = 1; } else @@ -354,6 +353,12 @@ internal void RemoveSourceGesture(HSpeedGesture gesture) sourceGestures.Remove(gesture); } + private bool AllowStartingHWithGesture() + { + if (smoothTargetSpeed < LOOP_0_ACTIVATION_THRESHOLD) return false; + return IsAibu() || VRControllerInput.IsILUGesture(); + } + private void UpdateSmoothTargetSpeed(HSceneFlagCtrl hCtrl, float deltaTime) { float targetSpeed = IDLE_SPEED; From 0f671c45a6a75a2c4080a5b73ac4448d127d4a6c Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 9 May 2024 14:25:44 +0000 Subject: [PATCH 221/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 202 ++++++++++++++++++++++++++++++--- 1 file changed, 187 insertions(+), 15 deletions(-) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index 6664d18..76fd3b8 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -13,17 +13,24 @@ public static class VRControllerInput internal static ViveRoleProperty roleR { get; private set; } = ViveRoleProperty.New(HandRole.RightHand); internal static ViveRoleProperty roleL { get; private set; } = ViveRoleProperty.New(HandRole.LeftHand); internal static ControllerManager controllerManager; + internal static bool inHandTrackingMode { get; private set; } internal static bool isDraggingScale { get { return twoHandedWorldGrab != null && twoHandedWorldGrab.canScale; } } private static TwoHandedWorldGrab _twoHandedWorldGrab; - private static TwoHandedWorldGrab twoHandedWorldGrab { - get { - if (_twoHandedWorldGrab == null || _twoHandedWorldGrab.gameObject == null) { + private static TwoHandedWorldGrab twoHandedWorldGrab + { + get + { + if (_twoHandedWorldGrab == null || _twoHandedWorldGrab.gameObject == null) + { _twoHandedWorldGrab = new GameObject("WorldGrabScale").AddComponent(); _twoHandedWorldGrab.enabled = false; } return _twoHandedWorldGrab; } } + private static bool leftHandTriggerAndGrip; + private static bool rightHandTriggerAndGrip; + internal static Vector3 handMidpointLocal { get { return Vector3.Lerp(VivePose.GetPose(roleL).pos, VivePose.GetPose(roleR).pos, 0.5f); } @@ -49,21 +56,27 @@ internal static HandRole GetHandRole(ViveRoleProperty roleProperty) /// internal static void UpdateSqueezeMovement() { + UpdateHandTrackingMode(); + VRControllerPointer.UpdateStabilizer(BetterVRPluginHelper.GetRightHand()); + Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; if (!vrOrigin) return; - bool leftHandTriggerAndGrip = + var wasHoldingLeftHandTriggerAndGrip = leftHandTriggerAndGrip; + var wasHoldingRightHandTriggerAndGrip = rightHandTriggerAndGrip; + + leftHandTriggerAndGrip = ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Trigger) && ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip); - bool rightHandTriggerAndGrip = + rightHandTriggerAndGrip = ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Trigger) && ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip); bool bothGrips = ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip) && ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip); - + bool twoHandedTurn = BetterVRPlugin.IsTwoHandedTurnEnabled() && bothGrips; - bool shouldScale = leftHandTriggerAndGrip && rightHandTriggerAndGrip; + bool shouldScale = leftHandTriggerAndGrip && rightHandTriggerAndGrip && !inHandTrackingMode; twoHandedWorldGrab.enabled = shouldScale || twoHandedTurn; twoHandedWorldGrab.canScale = shouldScale; @@ -73,14 +86,36 @@ internal static void UpdateSqueezeMovement() if (BetterVRPluginHelper.leftControllerCenter) { - BetterVRPluginHelper.leftControllerCenter.GetOrAddComponent().enabled = - leftHandTriggerAndGrip && !rightHandTriggerAndGrip && allowOneHandedWorldGrab; + var leftHandWorldGrab = BetterVRPluginHelper.leftControllerCenter.GetOrAddComponent(); + if (!leftHandTriggerAndGrip || rightHandTriggerAndGrip || !allowOneHandedWorldGrab) + { + leftHandWorldGrab.enabled = false; + } + else if (leftHandWorldGrab.enabled == false) + { + if (!inHandTrackingMode || + (!wasHoldingLeftHandTriggerAndGrip && IsCloseToWaist(BetterVRPluginHelper.leftControllerCenter.position))) + { + leftHandWorldGrab.enabled = true; + } + } } if (BetterVRPluginHelper.rightControllerCenter) { - BetterVRPluginHelper.rightControllerCenter.GetOrAddComponent().enabled = - rightHandTriggerAndGrip && !leftHandTriggerAndGrip && allowOneHandedWorldGrab; + var rightHandWorldGrab = BetterVRPluginHelper.rightControllerCenter.GetOrAddComponent(); + if (!rightHandTriggerAndGrip || leftHandTriggerAndGrip || !allowOneHandedWorldGrab) + { + rightHandWorldGrab.enabled = false; + } + else if (rightHandWorldGrab.enabled == false) + { + if (!inHandTrackingMode || + (!wasHoldingRightHandTriggerAndGrip && IsCloseToWaist(BetterVRPluginHelper.rightControllerCenter.position))) + { + rightHandWorldGrab.enabled = true; + } + } } if (!isDraggingScale && bothGrips && @@ -111,6 +146,134 @@ internal static void RestoreHandMidpointWorldPosition(Vector3? desiredWorldPosit vrOrigin.Translate((Vector3)desiredWorldPosition - vrOrigin.TransformPoint(handMidpointLocal), Space.World); } + internal static bool IsILUGesture() + { + return IsILUGesture(HandRole.LeftHand) || IsILUGesture(HandRole.RightHand); + } + + internal static bool IsILUGesture(HandRole handRole) + { + return inHandTrackingMode && + !ViveInput.GetPressEx(handRole, ControllerButton.AKeyTouch) && + !ViveInput.GetPressEx(handRole, ControllerButton.BkeyTouch) && + ViveInput.GetAxisEx(handRole, ControllerAxis.IndexCurl) < 0.3f && + ViveInput.GetAxisEx(handRole, ControllerAxis.MiddleCurl) > 0.8f && + ViveInput.GetAxisEx(handRole, ControllerAxis.RingCurl) > 0.8f && + ViveInput.GetAxisEx(handRole, ControllerAxis.PinkyCurl) < 0.3f; + } + + internal static bool IsChillGesture(HandRole handRole) + { + return inHandTrackingMode && + !ViveInput.GetPressEx(handRole, ControllerButton.AKeyTouch) && + !ViveInput.GetPressEx(handRole, ControllerButton.BkeyTouch) && + ViveInput.GetAxisEx(handRole, ControllerAxis.IndexCurl) > 0.8f && + ViveInput.GetAxisEx(handRole, ControllerAxis.MiddleCurl) > 0.8f && + ViveInput.GetAxisEx(handRole, ControllerAxis.RingCurl) > 0.8f && + ViveInput.GetAxisEx(handRole, ControllerAxis.PinkyCurl) < 0.3f; + } + + internal static bool IsPeaceGesture(HandRole handRole) + { + return inHandTrackingMode && + ViveInput.GetPressEx(handRole, ControllerButton.AKeyTouch) && + ViveInput.GetAxisEx(handRole, ControllerAxis.IndexCurl) < 0.3f && + ViveInput.GetAxisEx(handRole, ControllerAxis.MiddleCurl) < 0.3f && + ViveInput.GetAxisEx(handRole, ControllerAxis.RingCurl) > 0.8f && + ViveInput.GetAxisEx(handRole, ControllerAxis.PinkyCurl) > 0.8f; + } + + internal static bool TightGrip(HandRole handRole) + { + return inHandTrackingMode && + ViveInput.GetAxisEx(handRole, ControllerAxis.MiddleCurl) > 0.8f && + ViveInput.GetAxisEx(handRole, ControllerAxis.RingCurl) > 0.8f && + ViveInput.GetAxisEx(handRole, ControllerAxis.PinkyCurl) > 0.8f; + } + + internal static bool CanOpenMenuByGesture() + { + if (!IsPeaceGesture(HandRole.LeftHand)) return false; + + if (!ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.AKeyTouch) || + !TightGrip(HandRole.RightHand)) + { + return false; + } + + return ViveInput.GetPressUpEx(HandRole.RightHand, ControllerButton.Trigger); + } + + internal static bool CanCloseMenuByGesture() + { + if (!IsPeaceGesture(HandRole.RightHand)) return false; + + if (!ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.AKeyTouch) || + !TightGrip(HandRole.LeftHand)) + { + return false; + } + + return ViveInput.GetPressUpEx(HandRole.LeftHand, ControllerButton.Trigger); + } + + private static void UpdateHandTrackingMode() + { + if (!BetterVRPlugin.UseFingerTrackingGestures.Value) + { + inHandTrackingMode = false; + return; + } + + const float MIN_CURL_DIFF = 0.5f; + + if (inHandTrackingMode) + { + if (ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.AKey) || + ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.BKey) || + ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.AKey) || + ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.AKey)) + { + inHandTrackingMode = false; + } + } + else + { + if (GetCurlDiff(HandRole.LeftHand) > MIN_CURL_DIFF || GetCurlDiff(HandRole.RightHand) > MIN_CURL_DIFF) + { + inHandTrackingMode = true; + } + } + + if (inHandTrackingMode) + { + var buttonChecks = GameObject.FindObjectsOfType(); + foreach (var check in buttonChecks) + { + check.isOnDrag = check.isOnBeginDrag = false; + } + } + } + + private static float GetCurlDiff(HandRole handRole) + { + var middleCurl = ViveInput.GetAxisEx(handRole, ControllerAxis.MiddleCurl); + var pinkyCurl = ViveInput.GetAxisEx(handRole, ControllerAxis.PinkyCurl); + return Mathf.Abs(middleCurl - pinkyCurl); + } + + private static bool IsCloseToWaist(Vector3 position) + { + var range = BetterVRPlugin.PlayerScale * 0.25f; + Collider[] colliders = Physics.OverlapSphere(position, range, 1 << StripUpdater.H_CAMERA_LAYER); + foreach (Collider collider in colliders) + { + InteractionCollider interactionCollider = collider.GetComponent(); + if (interactionCollider != null && interactionCollider.IsCharacterVisible() && interactionCollider.name.Contains("osi")) return true; + } + return false; + } + public class TwoHandedWorldGrab : MonoBehaviour { private float scaleDraggingFactor; @@ -387,8 +550,17 @@ void Update() handRole = HandRole.RightHand; controllerCenter = BetterVRPluginHelper.rightControllerCenter; } + else if (CanOpenMenuByGesture()) + { + handRole = HandRole.LeftHand; + controllerCenter = BetterVRPluginHelper.leftControllerCenter; + } else { + if (CanCloseMenuByGesture()) + { + menu.Enable(false); + } handRole = HandRole.Invalid; } @@ -404,7 +576,7 @@ void Update() // Scale to the right size. if (originalScale == null) originalScale = menu.transform.localScale; Vector3 newScale = controllerCenter.lossyScale / 4096f; - menu.transform.localScale = + menu.transform.localScale = menu.transform.parent == null ? newScale : newScale / menu.transform.parent.lossyScale.x; SetLaserWidths(BetterVRPlugin.PlayerScale / 2f); @@ -416,7 +588,7 @@ void Update() controllerManager?.UpdateActivity(); } - if (ViveInput.GetPressEx(handRole, ControllerButton.Menu)) + if (ViveInput.GetPressEx(handRole, ControllerButton.Menu) || CanOpenMenuByGesture()) { // Move the menu with the hand. menu.transform.SetPositionAndRotation( @@ -427,8 +599,8 @@ void Update() private void SetLaserWidths(float width) { - SetLaserWidth(BetterVRPluginHelper.GetLeftHand(), (float) width); - SetLaserWidth(BetterVRPluginHelper.GetRightHand(), (float) width); + SetLaserWidth(BetterVRPluginHelper.GetLeftHand(), (float)width); + SetLaserWidth(BetterVRPluginHelper.GetRightHand(), (float)width); } private void SetLaserWidth(GameObject hand, float width) From 0cad9a4ac5635d50e9bf7f73f65034bc8e9a0141 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 9 May 2024 14:27:12 +0000 Subject: [PATCH 222/252] Update VRController.Pointer.cs --- BetterVR/VRController.Pointer.cs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/BetterVR/VRController.Pointer.cs b/BetterVR/VRController.Pointer.cs index 7b26e5f..2a5c524 100644 --- a/BetterVR/VRController.Pointer.cs +++ b/BetterVR/VRController.Pointer.cs @@ -39,7 +39,7 @@ private static void GetHandAndSetAngle(BetterVRPluginHelper.VR_Hand vrHand) // BetterVRPluginHelper.GetRightHand()?.GetComponentInChildren(); // if (raycaster.transform.parent?.parent != controllerModel) - if (controller.transform.Find("LaserPointer") == null) return; + if (controller.transform.Find("LaserPointer") == null) return; var oldAngles = raycaster.transform.localRotation.eulerAngles; @@ -51,8 +51,24 @@ private static void GetHandAndSetAngle(BetterVRPluginHelper.VR_Hand vrHand) BetterVRPlugin.Logger.LogInfo("Updated laser pointer rotation: " + oldAngles + " -> " + raycaster.transform.localRotation.eulerAngles); - var stabilizer = raycaster.GetComponentInParent(); - if (stabilizer) + UpdateStabilizer(controller); + } + + internal static void UpdateStabilizer(GameObject controller) + { + var stabilizer = + controller?. + GetComponentInChildren(true)?. + GetComponentInParent(); + if (!stabilizer) return; + + if (VRControllerInput.inHandTrackingMode) + { + // Hand tracking can flicker a lot and needs more stabilization. + stabilizer.positionThreshold = 1 / 256f; + stabilizer.rotationThreshold = 4; + } + else { // The vanilla laser pointer stabilization is too aggressive and causes a laggy feel. // Reduce the thresholds for a better balance between stability and responsiveness. From 1d6e89a20dada8f1057bcbfb9b5aa846f74c7c53 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Thu, 9 May 2024 14:28:33 +0000 Subject: [PATCH 223/252] Update VRGlove.cs --- BetterVR/VRGlove.cs | 75 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 18 deletions(-) diff --git a/BetterVR/VRGlove.cs b/BetterVR/VRGlove.cs index 9f1ca3c..bf50dad 100644 --- a/BetterVR/VRGlove.cs +++ b/BetterVR/VRGlove.cs @@ -212,18 +212,41 @@ void Update() { if (thumb && thumb.childCount > 0) { - if (ViveInput.GetPressEx(handRole, ControllerButton.AKeyTouch) || - ViveInput.GetPressEx(handRole, ControllerButton.BkeyTouch) || - ViveInput.GetPressEx(handRole, ControllerButton.PadTouch) || - ViveInput.GetPressEx(handRole, ControllerButton.MenuTouch)) + if (VRControllerInput.inHandTrackingMode) { - thumb.localRotation = Quaternion.Euler(0, 10 * rotationFactor, 5 * rotationFactor); - thumb.GetChild(0).localRotation = Quaternion.Euler(0, 5 * rotationFactor, 30 * rotationFactor); + if (ViveInput.GetPressEx(handRole, ControllerButton.AKeyTouch)) + { + thumb.localRotation = Quaternion.Euler(0, -20 * rotationFactor, 15 * rotationFactor); + thumb.GetChild(0).localRotation = Quaternion.Euler(0, -10* rotationFactor, 30 * rotationFactor); + thumb.GetChild(0).GetChild(0).localRotation = Quaternion.Euler(0, -45 * rotationFactor, 0 * rotationFactor); + } + else if (ViveInput.GetPressEx(handRole, ControllerButton.BkeyTouch)) { + thumb.localRotation = Quaternion.Euler(0, 0 * rotationFactor, 5 * rotationFactor); + thumb.GetChild(0).localRotation = Quaternion.Euler(0, 0 * rotationFactor, 30 * rotationFactor); + thumb.GetChild(0).GetChild(0).localRotation = Quaternion.Euler(0, -10 * rotationFactor, 0 * rotationFactor); + } + else + { + thumb.localRotation = Quaternion.Euler(0, 10 * rotationFactor, 5 * rotationFactor); + thumb.GetChild(0).localRotation = Quaternion.Euler(0, 5 * rotationFactor, 30 * rotationFactor); + thumb.GetChild(0).GetChild(0).localRotation = Quaternion.Euler(0, 0 * rotationFactor, 0 * rotationFactor); + } } else { - thumb.localRotation = Quaternion.Euler(0, 15 * rotationFactor, 20 * rotationFactor); - thumb.GetChild(0).localRotation = Quaternion.Euler(0, 10 * rotationFactor, 35 * rotationFactor); + if (ViveInput.GetPressEx(handRole, ControllerButton.AKeyTouch) || + ViveInput.GetPressEx(handRole, ControllerButton.BkeyTouch) || + ViveInput.GetPressEx(handRole, ControllerButton.PadTouch) || + ViveInput.GetPressEx(handRole, ControllerButton.MenuTouch)) + { + thumb.localRotation = Quaternion.Euler(0, 10 * rotationFactor, 5 * rotationFactor); + thumb.GetChild(0).localRotation = Quaternion.Euler(0, 5 * rotationFactor, 30 * rotationFactor); + } + else + { + thumb.localRotation = Quaternion.Euler(0, 15 * rotationFactor, 20 * rotationFactor); + thumb.GetChild(0).localRotation = Quaternion.Euler(0, 10 * rotationFactor, 35 * rotationFactor); + } } } @@ -232,18 +255,35 @@ void Update() float ringCurl = ViveInput.GetAxisEx(handRole, ControllerAxis.RingCurl); float pinkyCurl = ViveInput.GetAxisEx(handRole, ControllerAxis.PinkyCurl); - if (indexCurl != 0 || middleCurl != 0 || ringCurl != 0 || pinkyCurl != 0) + if (VRControllerInput.inHandTrackingMode && indexCurl != 0) { - UpdateAngle(index, indexCurl * 35); - UpdateAngle(middle, middleCurl * 60); - UpdateAngle(ring, ringCurl * 60); - UpdateAngle(pinky, pinkyCurl * 60); - return; + UpdateAngle(index, indexCurl * 65); } + else + { + float indexAngle = ViveInput.GetAxisEx(handRole, ControllerAxis.Trigger); - float indexAngle = 10; - if (ViveInput.GetPressEx(handRole, ControllerButton.TriggerTouch)) indexAngle = 30; - indexAngle += ViveInput.GetAxisEx(handRole, ControllerAxis.Trigger) * 5; + if (ViveInput.GetPressEx(handRole, ControllerButton.TriggerTouch)) + { + indexAngle = indexAngle * 5 + 30; + } + else + { + indexAngle = indexAngle * indexAngle * 45 + 10; + } + + UpdateAngle(index, indexAngle); + } + + if (VRControllerInput.inHandTrackingMode || middleCurl != 0 || ringCurl != 0 || pinkyCurl != 0) + { + float maxAngle = VRControllerInput.inHandTrackingMode ? 75 : 60; + + UpdateAngle(middle, middleCurl * maxAngle); + UpdateAngle(ring, ringCurl * maxAngle); + UpdateAngle(pinky, pinkyCurl * maxAngle); + return; + } float gripAngle = 10; if (ViveInput.GetPressEx(handRole, ControllerButton.TriggerTouch) || @@ -251,7 +291,6 @@ void Update() ViveInput.GetPressEx(handRole, ControllerButton.CapSenseGripTouch)) gripAngle = 70; gripAngle += ViveInput.GetAxisEx(handRole, ControllerAxis.CapSenseGrip) * 3; - UpdateAngle(index, indexAngle); UpdateAngle(middle, gripAngle); UpdateAngle(ring, gripAngle * 1.15f); UpdateAngle(pinky, gripAngle * 1.4f); From dc24843eeed56e32c3db9aa3dcde6f39875961ed Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 10 May 2024 02:15:30 +0000 Subject: [PATCH 224/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 79 ++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index 76fd3b8..4e3a7ea 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -12,7 +12,12 @@ public static class VRControllerInput internal static ViveRoleProperty roleH { get; private set; } = ViveRoleProperty.New(DeviceRole.Hmd); internal static ViveRoleProperty roleR { get; private set; } = ViveRoleProperty.New(HandRole.RightHand); internal static ViveRoleProperty roleL { get; private set; } = ViveRoleProperty.New(HandRole.LeftHand); - internal static ControllerManager controllerManager; + private static ControllerManager _controllerManager; + internal static ControllerManager controllerManager { + get { return _controllerManager ?? (_controllerManager = GameObject.FindObjectOfType()); } + set { _controllerManager = value; } + } + internal static bool inHandTrackingMode { get; private set; } internal static bool isDraggingScale { get { return twoHandedWorldGrab != null && twoHandedWorldGrab.canScale; } } private static TwoHandedWorldGrab _twoHandedWorldGrab; @@ -56,9 +61,15 @@ internal static HandRole GetHandRole(ViveRoleProperty roleProperty) /// internal static void UpdateSqueezeMovement() { + bool wasInHandTrackingMode = inHandTrackingMode; UpdateHandTrackingMode(); - VRControllerPointer.UpdateStabilizer(BetterVRPluginHelper.GetRightHand()); - + if (inHandTrackingMode != wasInHandTrackingMode) + { + UpdateCursorAttachPosition(); + } + VRControllerPointer.UpdateStabilizer(BetterVRPluginHelper.GetLeftHand(), freeze: TightGrip(HandRole.RightHand)); + VRControllerPointer.UpdateStabilizer(BetterVRPluginHelper.GetRightHand(), freeze: TightGrip(HandRole.LeftHand)); + Transform vrOrigin = BetterVRPluginHelper.VROrigin?.transform; if (!vrOrigin) return; @@ -175,8 +186,11 @@ internal static bool IsChillGesture(HandRole handRole) internal static bool IsPeaceGesture(HandRole handRole) { - return inHandTrackingMode && - ViveInput.GetPressEx(handRole, ControllerButton.AKeyTouch) && + if (!inHandTrackingMode) return false; + if (!ViveInput.GetPressEx(handRole, ControllerButton.AKeyTouch) && + !ViveInput.GetPressEx(handRole, ControllerButton.BkeyTouch)) return false; + + return ViveInput.GetAxisEx(handRole, ControllerAxis.IndexCurl) < 0.3f && ViveInput.GetAxisEx(handRole, ControllerAxis.MiddleCurl) < 0.3f && ViveInput.GetAxisEx(handRole, ControllerAxis.RingCurl) > 0.8f && @@ -195,26 +209,26 @@ internal static bool CanOpenMenuByGesture() { if (!IsPeaceGesture(HandRole.LeftHand)) return false; - if (!ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.AKeyTouch) || - !TightGrip(HandRole.RightHand)) + if (!ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.AKeyTouch) && + !ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.BkeyTouch)) { return false; } - return ViveInput.GetPressUpEx(HandRole.RightHand, ControllerButton.Trigger); + return TightGrip(HandRole.RightHand) && ViveInput.GetPressUpEx(HandRole.RightHand, ControllerButton.Trigger); } internal static bool CanCloseMenuByGesture() { if (!IsPeaceGesture(HandRole.RightHand)) return false; - if (!ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.AKeyTouch) || - !TightGrip(HandRole.LeftHand)) + if (!ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.AKeyTouch) && + !ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.BkeyTouch)) { return false; } - return ViveInput.GetPressUpEx(HandRole.LeftHand, ControllerButton.Trigger); + return TightGrip(HandRole.LeftHand) && ViveInput.GetPressUpEx(HandRole.LeftHand, ControllerButton.Trigger); } private static void UpdateHandTrackingMode() @@ -255,6 +269,30 @@ private static void UpdateHandTrackingMode() } } + private static void UpdateCursorAttachPosition() + { + if (BetterVRPluginHelper.leftCursorAttach != null) + { + if (inHandTrackingMode && BetterVRPluginHelper.leftGlove != null) + { + BetterVRPluginHelper.leftCursorAttach.position = BetterVRPluginHelper.leftGlove.transform.TransformPoint(new Vector3(-3f, 0.25f, 0.75f)); + } + else { + BetterVRPluginHelper.leftCursorAttach.localPosition = new Vector3(0, 0.0625f, 0.125f); + } + } + + if (BetterVRPluginHelper.rightCursorAttach != null) + { + if (inHandTrackingMode && BetterVRPluginHelper.rightGlove != null) { + BetterVRPluginHelper.rightCursorAttach.position = BetterVRPluginHelper.rightGlove.transform.TransformPoint(new Vector3(3f, 0.25f, 0.75f)); + } + else { + BetterVRPluginHelper.rightCursorAttach.localPosition = new Vector3(0, 0.0625f, 0.125f); + } + } + } + private static float GetCurlDiff(HandRole handRole) { var middleCurl = ViveInput.GetAxisEx(handRole, ControllerAxis.MiddleCurl); @@ -505,7 +543,23 @@ void Update() var camera = BetterVRPluginHelper.VRCamera; - if (menu == null || camera == null) return; + if (menu == null || camera == null) + { + // Allow toggling right hand laser in select scene. + if (CanOpenMenuByGesture()) + { + controllerManager?.SetRightLaserPointerActive(true); + controllerManager?.UpdateActivity(); + } + else if (CanCloseMenuByGesture()) + { + controllerManager?.SetRightLaserPointerActive(false); + controllerManager?.UpdateActivity(); + } + // The controller manager might become stale later, clear the cache. + controllerManager = null; + return; + } if (ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Menu)) { @@ -581,7 +635,6 @@ void Update() SetLaserWidths(BetterVRPlugin.PlayerScale / 2f); - if (controllerManager == null) controllerManager = GameObject.FindObjectOfType(); // Hide the laser on the laser hand and show the laser on the other hand. controllerManager?.SetLeftLaserPointerActive(handRole != HandRole.LeftHand); controllerManager?.SetRightLaserPointerActive(handRole != HandRole.RightHand); From f9e7a025c076cd819aed75614d25bd974e911bc9 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 10 May 2024 02:15:59 +0000 Subject: [PATCH 225/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index 4bb8dda..72b9177 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -14,7 +14,7 @@ namespace BetterVR public partial class BetterVRPlugin : BaseUnityPlugin { public const string GUID = "BetterVR"; - public const string Version = "0.53"; + public const string Version = "0.54"; internal static new ManualLogSource Logger { get; private set; } #if DEBUG From 042b43aba0a9be7e0bda12d0b498163802a1e3c2 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 10 May 2024 02:17:05 +0000 Subject: [PATCH 226/252] Update VRController.Pointer.cs --- BetterVR/VRController.Pointer.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/BetterVR/VRController.Pointer.cs b/BetterVR/VRController.Pointer.cs index 2a5c524..b06c346 100644 --- a/BetterVR/VRController.Pointer.cs +++ b/BetterVR/VRController.Pointer.cs @@ -51,18 +51,23 @@ private static void GetHandAndSetAngle(BetterVRPluginHelper.VR_Hand vrHand) BetterVRPlugin.Logger.LogInfo("Updated laser pointer rotation: " + oldAngles + " -> " + raycaster.transform.localRotation.eulerAngles); - UpdateStabilizer(controller); + UpdateStabilizer(controller, false); } - internal static void UpdateStabilizer(GameObject controller) + internal static void UpdateStabilizer(GameObject controller, bool freeze) { var stabilizer = controller?. GetComponentInChildren(true)?. GetComponentInParent(); if (!stabilizer) return; - - if (VRControllerInput.inHandTrackingMode) + + if (freeze) + { + stabilizer.positionThreshold = 1 / 32f; + stabilizer.rotationThreshold = 30; + } + else if (VRControllerInput.inHandTrackingMode) { // Hand tracking can flicker a lot and needs more stabilization. stabilizer.positionThreshold = 1 / 256f; From 5e94f364d48cdb238963dc5a888ae0f77db7639e Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 10 May 2024 02:17:56 +0000 Subject: [PATCH 227/252] Update HSpeedGesture.cs --- BetterVR/HSpeedGesture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/HSpeedGesture.cs b/BetterVR/HSpeedGesture.cs index fbd4845..2de9f45 100644 --- a/BetterVR/HSpeedGesture.cs +++ b/BetterVR/HSpeedGesture.cs @@ -278,7 +278,7 @@ void FixedUpdate() UpdateOutput(hCtrl); if (IsAibu() && !hCtrl.isGaugeHit && hCtrl.loopType >= 0 && hCtrl.loopType <= 2 && - smoothTargetSpeed < LOOP_0_DEACTIVATION_THRESHOLD) + smoothTargetSpeed < LOOP_0_DEACTIVATION_THRESHOLD && !VRControllerInput.IsILUGesture()) { // Allow stopping action with hand motion in Aibu mode. StopMotion(hCtrl); From 4086b6373c453f77ebfc77d3eebffc30643fe71c Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 10 May 2024 02:18:21 +0000 Subject: [PATCH 228/252] Update release.cmd --- release.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.cmd b/release.cmd index bcca202..1cb808c 100644 --- a/release.cmd +++ b/release.cmd @@ -1,7 +1,7 @@ ::Zips the dll into the correct directory structure for release ::Make sure to increment the version -set version=0.53 +set version=0.6 set name=HS2_BetterVR IF NOT EXIST "../releases/%name%/BepInEx/plugins" MKDIR "../releases/%name%/BepInEx/plugins" From b3578d966180a7497bdf5338957c3814d393d6b3 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Fri, 10 May 2024 02:18:40 +0000 Subject: [PATCH 229/252] Update BetterVRPlugin.cs --- BetterVR/BetterVRPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterVR/BetterVRPlugin.cs b/BetterVR/BetterVRPlugin.cs index 72b9177..bf37b4b 100644 --- a/BetterVR/BetterVRPlugin.cs +++ b/BetterVR/BetterVRPlugin.cs @@ -14,7 +14,7 @@ namespace BetterVR public partial class BetterVRPlugin : BaseUnityPlugin { public const string GUID = "BetterVR"; - public const string Version = "0.54"; + public const string Version = "0.6"; internal static new ManualLogSource Logger { get; private set; } #if DEBUG From 65bc20138dd4a36485107bffc1f60e43320f3bfb Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 12 May 2024 23:43:15 +0000 Subject: [PATCH 230/252] Update BetterVRPlugin.Helper.cs --- BetterVR/BetterVRPlugin.Helper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BetterVR/BetterVRPlugin.Helper.cs b/BetterVR/BetterVRPlugin.Helper.cs index 552bac9..54cf67a 100644 --- a/BetterVR/BetterVRPlugin.Helper.cs +++ b/BetterVR/BetterVRPlugin.Helper.cs @@ -103,7 +103,7 @@ internal static Transform leftCursorAttach if (CreateTransformIfNotPresent(ref _leftCursorAttach, parent: leftControllerCenter)) { _leftCursorAttach.name = "LeftCursorAttach"; - _leftCursorAttach.localPosition = Vector3.forward * 0.1f; + _leftCursorAttach.localPosition = new Vector3(0, 0.0625f, 0.125f); } return _leftCursorAttach; } @@ -115,7 +115,7 @@ internal static Transform rightCursorAttach if (CreateTransformIfNotPresent(ref _rightCursorAttach, parent: rightControllerCenter)) { _rightCursorAttach.name = "RightCursorAttach"; - _rightCursorAttach.localPosition = Vector3.forward * 0.1f; + _rightCursorAttach.localPosition = new Vector3(0, 0.0625f, 0.125f); } return _rightCursorAttach; } From 66cb5953e183ae1bb1b3b752014a037d4afca8e3 Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 12 May 2024 23:47:11 +0000 Subject: [PATCH 231/252] Update VRController.Input.cs --- BetterVR/VRController.Input.cs | 89 +++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 6 deletions(-) diff --git a/BetterVR/VRController.Input.cs b/BetterVR/VRController.Input.cs index 4e3a7ea..63ef86b 100644 --- a/BetterVR/VRController.Input.cs +++ b/BetterVR/VRController.Input.cs @@ -1,4 +1,5 @@ using TMPro; +using HTC.UnityPlugin.Pointer3D; using HTC.UnityPlugin.Vive; using Illusion.Extensions; using System; @@ -35,6 +36,8 @@ private static TwoHandedWorldGrab twoHandedWorldGrab } private static bool leftHandTriggerAndGrip; private static bool rightHandTriggerAndGrip; + private static Vector3? originalLeftRaycasterPosition; + private static Vector3? originalRightRaycasterPosition; internal static Vector3 handMidpointLocal { @@ -48,6 +51,16 @@ internal static float handDistanceLocal return Vector3.Distance(VivePose.GetPose(VRControllerInput.roleL).pos, VivePose.GetPose(VRControllerInput.roleR).pos); } } + + internal static Pointer3DRaycaster leftRaycaster + { + get { return BetterVRPluginHelper.GetLeftHand()?.GetComponentInChildren(true); } + } + + internal static Pointer3DRaycaster rightRaycaster + { + get { return BetterVRPluginHelper.GetRightHand()?.GetComponentInChildren(true); } + } internal static HandRole GetHandRole(ViveRoleProperty roleProperty) { @@ -205,7 +218,25 @@ internal static bool TightGrip(HandRole handRole) ViveInput.GetAxisEx(handRole, ControllerAxis.PinkyCurl) > 0.8f; } - internal static bool CanOpenMenuByGesture() + internal static bool TightGrip(ViveRoleProperty handRole) + { + return inHandTrackingMode && + ViveInput.GetAxis(handRole, ControllerAxis.MiddleCurl) > 0.8f && + ViveInput.GetAxis(handRole, ControllerAxis.RingCurl) > 0.8f && + ViveInput.GetAxis(handRole, ControllerAxis.PinkyCurl) > 0.8f; + } + + internal static bool CanStripUsingGesture(ViveRoleProperty handRole, bool wasGrabbing) + { + if (!inHandTrackingMode || ViveInput.GetAxis(handRole, ControllerAxis.MiddleCurl) < 0.5f) return false; + if (wasGrabbing) return true; + + return ViveInput.GetAxis(handRole, ControllerAxis.IndexCurl) < 0.5f && + ViveInput.GetAxis(handRole, ControllerAxis.MiddleCurl) > 0.6f && + ViveInput.GetAxis(handRole, ControllerAxis.PinkyCurl) < 0.4f; + } + + internal static bool CanOpenLeftMenuByGesture() { if (!IsPeaceGesture(HandRole.LeftHand)) return false; @@ -218,7 +249,7 @@ internal static bool CanOpenMenuByGesture() return TightGrip(HandRole.RightHand) && ViveInput.GetPressUpEx(HandRole.RightHand, ControllerButton.Trigger); } - internal static bool CanCloseMenuByGesture() + internal static bool CanOpenRightMenuByGesture() { if (!IsPeaceGesture(HandRole.RightHand)) return false; @@ -231,6 +262,26 @@ internal static bool CanCloseMenuByGesture() return TightGrip(HandRole.LeftHand) && ViveInput.GetPressUpEx(HandRole.LeftHand, ControllerButton.Trigger); } + internal static bool CanCloseMenuByGesture() + { + if (!TightGrip(HandRole.LeftHand) || !TightGrip(HandRole.RightHand)) return false; + + if (!ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.AKeyTouch) && + !ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.BkeyTouch)) + { + return false; + } + + if (!ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.AKeyTouch) && + !ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.BkeyTouch)) + { + return false; + } + + return ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Trigger) && + ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Trigger); + } + private static void UpdateHandTrackingMode() { if (!BetterVRPlugin.UseFingerTrackingGestures.Value) @@ -349,7 +400,7 @@ void OnEnable() } else { - desiredHandMidpointWorldCoordinates = vrOrigin.transform.TransformPoint(VRControllerInput.handMidpointLocal); + desiredHandMidpointWorldCoordinates = vrOrigin.transform.TransformPoint(handMidpointLocal); lastHandPositionDifference = VivePose.GetPose(roleR).pos - VivePose.GetPose(roleL).pos; } } @@ -546,13 +597,19 @@ void Update() if (menu == null || camera == null) { // Allow toggling right hand laser in select scene. - if (CanOpenMenuByGesture()) + if (CanOpenLeftMenuByGesture()) { controllerManager?.SetRightLaserPointerActive(true); controllerManager?.UpdateActivity(); } + else if (CanOpenRightMenuByGesture()) + { + controllerManager?.SetLeftLaserPointerActive(true); + controllerManager?.UpdateActivity(); + } else if (CanCloseMenuByGesture()) { + controllerManager?.SetLeftLaserPointerActive(false); controllerManager?.SetRightLaserPointerActive(false); controllerManager?.UpdateActivity(); } @@ -589,6 +646,8 @@ void Update() controllerManager?.SetLeftLaserPointerActive(false); controllerManager?.SetRightLaserPointerActive(false); controllerManager?.UpdateActivity(); + if (originalLeftRaycasterPosition != null && leftRaycaster) leftRaycaster.transform.localPosition = originalLeftRaycasterPosition.Value; + if (originalRightRaycasterPosition != null && rightRaycaster) rightRaycaster.transform.localPosition = originalRightRaycasterPosition.Value; handRole = HandRole.Invalid; return; } @@ -604,10 +663,27 @@ void Update() handRole = HandRole.RightHand; controllerCenter = BetterVRPluginHelper.rightControllerCenter; } - else if (CanOpenMenuByGesture()) + else if (CanOpenLeftMenuByGesture()) { handRole = HandRole.LeftHand; controllerCenter = BetterVRPluginHelper.leftControllerCenter; + var raycaster = rightRaycaster; + if (raycaster) + { + if (originalRightRaycasterPosition == null) originalRightRaycasterPosition = raycaster.transform.localPosition; + raycaster.transform.localPosition = -0.1f * Vector3.forward; + } + } + else if (CanOpenRightMenuByGesture()) + { + handRole = HandRole.RightHand; + controllerCenter = BetterVRPluginHelper.rightControllerCenter; + var raycaster = leftRaycaster; + if (raycaster) + { + if (originalLeftRaycasterPosition == null) originalLeftRaycasterPosition = raycaster.transform.localPosition; + raycaster.transform.localPosition = -0.1f * Vector3.forward; + } } else { @@ -641,7 +717,8 @@ void Update() controllerManager?.UpdateActivity(); } - if (ViveInput.GetPressEx(handRole, ControllerButton.Menu) || CanOpenMenuByGesture()) + if (ViveInput.GetPressEx(handRole, ControllerButton.Menu) || + CanOpenLeftMenuByGesture() || CanOpenRightMenuByGesture()) { // Move the menu with the hand. menu.transform.SetPositionAndRotation( From 32d2940991bf53aa75d9f2eb1d1531f69749702d Mon Sep 17 00:00:00 2001 From: KhLTz <151600406+KhLTz@users.noreply.github.com> Date: Sun, 12 May 2024 23:48:00 +0000 Subject: [PATCH 232/252] Update VrController.StripUpdater.cs --- BetterVR/VrController.StripUpdater.cs | 93 ++++++++++++++++++--------- 1 file changed, 64 insertions(+), 29 deletions(-) diff --git a/BetterVR/VrController.StripUpdater.cs b/BetterVR/VrController.StripUpdater.cs index 5d50002..95fec8f 100644 --- a/BetterVR/VrController.StripUpdater.cs +++ b/BetterVR/VrController.StripUpdater.cs @@ -14,19 +14,19 @@ public class StripUpdater internal const int H_CAMERA_LAYER = 22; internal static readonly Color[] STRIP_INDICATOR_COLORS = new Color[] { Color.blue, Color.red, Color.cyan, Color.magenta, Color.yellow, Color.green, Color.white, Color.black }; - + private const float STRIP_START_RANGE = 0.5f; private const float STRIP_MIN_DRAG_RANGE = 0.75f; private Canvas clothIconCanvas; private List clothIcons = new List(); + private List strippedClothIcons = new List(); private bool finishedLoadingClothIcons = false; private ViveRoleProperty handRole; private Vector3 stripStartPos; private bool canClothe; private StripCollider grabbedStripCollider; private MeshRenderer stripIndicator; - - + private bool grabbing; internal StripUpdater(ViveRoleProperty handRole) { @@ -40,16 +40,16 @@ internal void CheckStrip(bool enable) Vector3 handPos = BetterVRPluginHelper.VROrigin.transform.TransformPoint(VivePose.GetPose(handRole).pos); - if (!enable || - ViveInput.GetPress(handRole, ControllerButton.Grip)) // Disable stripping during possible movements + if (!enable || (!VRControllerInput.inHandTrackingMode && ViveInput.GetPress(handRole, ControllerButton.Grip))) { grabbedStripCollider = null; canClothe = false; stripIndicator?.gameObject.SetActive(false); + grabbing = false; return; } - if (ViveInput.GetPressUp(handRole, ControllerButton.Trigger)) + if (!VRControllerInput.inHandTrackingMode && ViveInput.GetPressUp(handRole, ControllerButton.Trigger)) { if (grabbedStripCollider != null && canClothe) { @@ -65,18 +65,44 @@ internal void CheckStrip(bool enable) canClothe = false; grabbedStripCollider = null; stripIndicator?.gameObject.SetActive(false); + grabbing = false; return; } - - if (ViveInput.GetPress(handRole, ControllerButton.Trigger)) + + grabbing = VRControllerInput.inHandTrackingMode? + (VRControllerInput.CanStripUsingGesture(handRole, wasGrabbing: grabbing)) : ViveInput.GetPress(handRole, ControllerButton.Trigger); + if (grabbing) { if (canClothe) { grabbedStripCollider = FindClosestStripCollider(handPos, STRIP_START_RANGE * BetterVRPlugin.PlayerScale, 1, 2); UpdateStripIndicator(); } - else if (grabbedStripCollider != null && Vector3.Distance(handPos, stripStartPos) > STRIP_MIN_DRAG_RANGE * BetterVRPlugin.PlayerScale) + else { + if (finishedLoadingClothIcons) + { + for (int i = 0; i < clothIcons.Count; i++) + { + if (clothIcons[i] == null || strippedClothIcons[i] == null) + { + finishedLoadingClothIcons = false; + break; + } + if (clothIcons[i].activeSelf) + { + clothIcons[i].SetActive(false); + strippedClothIcons[i].SetActive(true); + break; + } + } + } + + if (grabbedStripCollider == null || Vector3.Distance(handPos, stripStartPos) < STRIP_MIN_DRAG_RANGE * BetterVRPlugin.PlayerScale) + { + return; + } + if (Vector3.Angle(handPos - stripStartPos, grabbedStripCollider.transform.position - stripStartPos) > 90) { if (grabbedStripCollider.StripMore() && BetterVRPlugin.HapticFeedbackIntensity.Value > 0) @@ -96,7 +122,7 @@ internal void CheckStrip(bool enable) return; } - grabbedStripCollider = FindClosestStripCollider(handPos, STRIP_START_RANGE * BetterVRPlugin.PlayerScale, 0, 1); + grabbedStripCollider = FindClosestStripCollider(handPos, STRIP_START_RANGE * BetterVRPlugin.PlayerScale, 0, VRControllerInput.inHandTrackingMode ? (byte) 2 : (byte) 1); UpdateStripIndicator(); stripStartPos = handPos; canClothe = (grabbedStripCollider == null); @@ -116,6 +142,7 @@ private void LoadClothIconsIfNeeded() } while (clothIcons.Count < 8) clothIcons.Add(null); + while (strippedClothIcons.Count < 8) strippedClothIcons.Add(null); if (!clothIconCanvas) clothIconCanvas = new GameObject("ClothIconCanvas").AddComponent(); clothIconCanvas.transform.SetParent(stripIndicator.transform, false); @@ -126,7 +153,7 @@ private void LoadClothIconsIfNeeded() bool waitingForIcons = false; for (int i = 0; i < 8; i++) { - if (clothIcons[i] != null) continue; + if (clothIcons[i] != null && strippedClothIcons[i] != null) continue; var allClothButtons = hSceneSprite.objCloth.objs; if (allClothButtons == null || allClothButtons.Count <= i) @@ -135,33 +162,40 @@ private void LoadClothIconsIfNeeded() continue; } var buttons = allClothButtons[i].buttons; - var buttonIndex = (i == 3 || i == 5) ? 1 : 0; - if (buttons.Length <= buttonIndex) + if (buttons.Length < 2) { waitingForIcons = true; continue; } - GameObject clothIcon = GameObject.Instantiate(buttons[buttonIndex].gameObject); + GameObject clothIcon = GameObject.Instantiate(buttons[0].gameObject); + GameObject strippedClothIcon = GameObject.Instantiate(buttons[1].gameObject); Object.Destroy(clothIcon.GetComponent