From 1dafd7b4f70e1946ad90b2ded71afb04a905eaa5 Mon Sep 17 00:00:00 2001 From: OrangeSpork <57274555+OrangeSpork@users.noreply.github.com> Date: Sat, 27 Mar 2021 15:08:47 -0600 Subject: [PATCH] Boop Support --- HS2VR/HS2VR.csproj | 2 + HS2VR/VRCollider.cs | 172 ++++++++++++++++++++++++++++++++++++++ HS2VR/VRColliderHelper.cs | 55 ++++++++++++ HS2VR/VRPlugin.cs | 7 +- 4 files changed, 234 insertions(+), 2 deletions(-) create mode 100644 HS2VR/VRCollider.cs create mode 100644 HS2VR/VRColliderHelper.cs diff --git a/HS2VR/HS2VR.csproj b/HS2VR/HS2VR.csproj index b971d4b..c0ad50c 100644 --- a/HS2VR/HS2VR.csproj +++ b/HS2VR/HS2VR.csproj @@ -100,6 +100,8 @@ + + diff --git a/HS2VR/VRCollider.cs b/HS2VR/VRCollider.cs new file mode 100644 index 0000000..2c84c84 --- /dev/null +++ b/HS2VR/VRCollider.cs @@ -0,0 +1,172 @@ +using IllusionUtility.GetUtility; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using VRGIN.Core; + +namespace HS2VR +{ + // Code contribute from thojmr - Much Appreciated + public static class VRCollider + { + /// + /// Searches for dynamic bones, and when found links them to the colliders set on the controllers + /// + internal static void SetVRControllerColliderToDynamicBones() + { + //Get all dynamic bones + var dynamicBonesV2 = GameObject.FindObjectsOfType(); + var dynamicBones = GameObject.FindObjectsOfType(); + if (dynamicBonesV2.Length == 0 && dynamicBones.Length == 0) + { + VRLog.Info("No DB Bones Present, Nothing To Do"); + return; + } + + //Get the controller objects we want to attach colliders to.transform.gameObject + var leftHand = VR.Controller.Left?.gameObject; + var rightHand = VR.Controller.Right?.gameObject; + if (leftHand == null && rightHand == null) + { + VRLog.Info("No Hands, skipping for a round"); + return; + } + + VRLog.Info("Found Hands, Updating DB Bones"); + + //Attach a dynamic bone collider to each, then link that to all dynamic bones + if (leftHand) AttachToControllerAndLink(leftHand, leftHand.GetInstanceID().ToString(), dynamicBones, dynamicBonesV2); + if (rightHand) AttachToControllerAndLink(rightHand, rightHand.GetInstanceID().ToString(), dynamicBones, dynamicBonesV2); + } + + + /// + /// Gets the transform of the squeeze button + /// + internal static Transform GetColliderPosition(GameObject hand) + { + //render location + var renderTf = hand.transform.FindLoop("Model"); + if (renderTf == null) + { + VRLog.Info("No Render Loop Found"); + return null; + } + + return renderTf; + } + + + /// + /// Adds the colliders to the controllers, and then links the dynamic bones + /// + internal static void AttachToControllerAndLink(GameObject controller, string name, DynamicBone[] dynamicBones, DynamicBone_Ver02[] dynamicBonesV2) + { + //For each vr controller add dynamic bone collider to it + var controllerCollider = GetOrAttachCollider(controller, name); + if (controllerCollider == null) return; + + //For each controller, make it collidable with all dynaic bones (Did I miss any?) + AddControllerColliderToDBv2(controllerCollider, dynamicBonesV2); + AddControllerColliderToDB(controllerCollider, dynamicBones); + } + + + /// + /// Checks for existing controller collider, or creates them + /// + internal static DynamicBoneCollider GetOrAttachCollider(GameObject controllerGameObject, string colliderName) + { + if (controllerGameObject == null) return null; + + //Check for existing DB collider that may have been attached earlier + var existingDBCollider = controllerGameObject.GetComponentInChildren(); + if (existingDBCollider == null) + { + //Add a DB collider to the controller + return AddDBCollider(controllerGameObject, colliderName); + } + + return existingDBCollider; + } + + + /// + /// 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, + Vector3 colliderCenter = new Vector3(), DynamicBoneCollider.Direction colliderDirection = default) + { + var renderModelTf = GetColliderPosition(controllerGameObject); + if (renderModelTf == null) return null; + + //Build the dynamic bone collider + var colliderObject = new GameObject(colliderName); + var collider = colliderObject.AddComponent(); + collider.m_Radius = colliderRadius; + collider.m_Height = collierHeight; + 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; + + VRLog.Info($"Added DB Collider to {controllerGameObject.name}"); + + return collider; + } + + + /// + /// Links V2 dynamic bones to a controller collider + /// + internal static void AddControllerColliderToDBv2(DynamicBoneCollider controllerCollider, DynamicBone_Ver02[] dynamicBones) + { + if (controllerCollider == 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++) + { + //Check for existing interaction + if (!dynamicBones[z].Colliders.Contains(controllerCollider)) + { + dynamicBones[z].Colliders.Add(controllerCollider); + newDBCount++; + } + } + + } + + /// + /// Links V1 dynamic bones to a controller collider + /// + internal static void AddControllerColliderToDB(DynamicBoneCollider controllerCollider, DynamicBone[] dynamicBones) + { + if (controllerCollider == 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++) + { + //Check for existing interaction + if (!dynamicBones[z].m_Colliders.Contains(controllerCollider)) + { + dynamicBones[z].m_Colliders.Add(controllerCollider); + newDBCount++; + } + } + } + + } +} diff --git a/HS2VR/VRColliderHelper.cs b/HS2VR/VRColliderHelper.cs new file mode 100644 index 0000000..553d42a --- /dev/null +++ b/HS2VR/VRColliderHelper.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using VRGIN.Core; + +namespace HS2VR +{ + // Code contributed by thojmr + public static class VRColliderHelper + { + internal static bool coroutineActive = false; + internal static VRPlugin pluginInstance; + + + internal static void TriggerHelperCoroutine() + { + //Only trigger if not already running, and in main game + if (coroutineActive) return; + coroutineActive = true; + + pluginInstance.StartCoroutine(LoopEveryXSeconds()); + } + + + internal static void StopHelperCoroutine() + { + pluginInstance.StopCoroutine(LoopEveryXSeconds()); + coroutineActive = false; + } + + + /// + /// Got tired of searching for the correct hooks, just check for new dynamic bones on a loop. Genious! (Should be able to use CharCustFunCtrl for this later) + /// + internal static IEnumerator LoopEveryXSeconds() + { + while (coroutineActive) + { + try + { + VRCollider.SetVRControllerColliderToDynamicBones(); + } + catch (Exception e) + { + VRLog.Error("Error in Collider Helper: " + e.Message, e.StackTrace); + } + yield return new WaitForSeconds(3); + } + } + } +} diff --git a/HS2VR/VRPlugin.cs b/HS2VR/VRPlugin.cs index 9b9dd89..e5fce8f 100644 --- a/HS2VR/VRPlugin.cs +++ b/HS2VR/VRPlugin.cs @@ -12,7 +12,7 @@ namespace HS2VR /// /// This is an example for a VR plugin. At the same time, it also functions as a generic one. /// - [BepInPlugin(GUID: "HS2VR.unofficial", Name: "HS2VR", Version: "0.0.4.0")] + [BepInPlugin(GUID: "HS2VR.unofficial", Name: "HS2VR", Version: "0.0.5.0")] [BepInProcess("HoneySelect2")] [BepInProcess("StudioNEOV2")] public class VRPlugin : BaseUnityPlugin @@ -34,7 +34,7 @@ public string Version { get { - return "0.0.4.0"; + return "0.0.5.0"; } } @@ -59,6 +59,9 @@ void Awake() { VR_ACTIVATED = true; VRLoader.Create(true); + + VRColliderHelper.pluginInstance = this; + VRColliderHelper.TriggerHelperCoroutine(); } else {