diff --git a/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Components/SteeringWheelPickup.cs b/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Components/SteeringWheelPickup.cs index d809150..7981d63 100644 --- a/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Components/SteeringWheelPickup.cs +++ b/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Components/SteeringWheelPickup.cs @@ -1,12 +1,16 @@ using ABI_RC.Core.InteractionSystem; using ABI_RC.Core.InteractionSystem.Base; +using ABI_RC.Core.Savior; using UnityEngine; namespace NAK.RCCVirtualSteeringWheel; public class SteeringWheelPickup : Pickupable { - #region Public Properties + internal SteeringWheelRoot root; + + #region Pickupable Properties + public override bool DisallowTheft => true; public override float MaxGrabDistance => 0.8f; public override float MaxPushDistance => 0f; @@ -14,11 +18,12 @@ public class SteeringWheelPickup : Pickupable public override bool IsObjectRotationAllowed => false; public override bool IsObjectPushPullAllowed => false; public override bool IsObjectUseAllowed => false; - public override bool CanPickup => IsPickupable && !IsPickedUp; - internal SteeringWheelRoot root; - #endregion - - #region Public Methods + public override bool CanPickup => IsPickupable && !IsPickedUp && MetaPort.Instance.isUsingVr; + + #endregion Pickupable Properties + + #region Pickupable Methods + public override void OnUseDown(InteractionContext context) { } public override void OnUseUp(InteractionContext context) { } public override void OnFlingTowardsTarget(Vector3 target) { } @@ -32,5 +37,6 @@ public class SteeringWheelPickup : Pickupable if (ControllerRay?.transform != null) root.StopTrackingTransform(ControllerRay.transform); } - #endregion + + #endregion Pickupable Methods } \ No newline at end of file diff --git a/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Components/SteeringWheelRoot.cs b/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Components/SteeringWheelRoot.cs index cc293aa..b8008b8 100644 --- a/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Components/SteeringWheelRoot.cs +++ b/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Components/SteeringWheelRoot.cs @@ -65,6 +65,7 @@ public class SteeringWheelRoot : MonoBehaviour #region Public Properties private bool IsWheelBeingHeld => _pickups[0].IsPickedUp || _pickups[1].IsPickedUp; + private bool IsWheelInactive => !IsWheelBeingHeld && _averageAngle == 0f; #endregion Public Properties @@ -75,6 +76,8 @@ public class SteeringWheelRoot : MonoBehaviour private float _originalSteeringWheelAngleMultiplier; private float _originalSteeringWheelSign; + private bool _originalCounterSteer; + private bool _originalSteerSmoothing; private readonly List _trackedTransforms = new(); private readonly List _lastPositions = new(); @@ -84,6 +87,7 @@ public class SteeringWheelRoot : MonoBehaviour private float _averageAngle; private float _timeWheelReleased = -1f; private const float RETURN_TO_CENTER_DURATION = 2f; + private const float RETURN_START_DELAY = 0.1f; #endregion Private Variables @@ -115,21 +119,7 @@ public class SteeringWheelRoot : MonoBehaviour { if (trans == null) return; - var currentAngle = 0f; - if (_isTracking) - { - var sum = 0f; - var validTransforms = 0; - for (var i = 0; i < _trackedTransforms.Count; i++) - if (_trackedTransforms[i] != null) - { - sum += _totalAngles[i]; - validTransforms++; - } - - if (validTransforms > 0) - currentAngle = sum / validTransforms; - } + var currentAngle = _isTracking ? CalculateAverageAngle(_trackedTransforms, _totalAngles) : 0f; _trackedTransforms.Add(trans); _lastPositions.Add(GetLocalPositionWithoutRotation(transform.position)); @@ -142,7 +132,7 @@ public class SteeringWheelRoot : MonoBehaviour var index = _trackedTransforms.IndexOf(trans); if (index == -1) return; - var currentAverage = CalculateCurrentAverage(); + var currentAverage = CalculateAverageAngle(_trackedTransforms, _totalAngles); _trackedTransforms.RemoveAt(index); _lastPositions.RemoveAt(index); _totalAngles.RemoveAt(index); @@ -153,21 +143,7 @@ public class SteeringWheelRoot : MonoBehaviour for (var i = 0; i < _totalAngles.Count; i++) _totalAngles[i] = currentAverage; } - - private float CalculateCurrentAverage() - { - var sum = 0f; - var validTransforms = 0; - for (var i = 0; i < _trackedTransforms.Count; i++) - if (_trackedTransforms[i] != null) - { - sum += _totalAngles[i]; - validTransforms++; - } - - return validTransforms > 0 ? sum / validTransforms : 0f; - } - + #endregion Public Methods #region Private Methods @@ -176,8 +152,8 @@ public class SteeringWheelRoot : MonoBehaviour { _originalSteeringWheelAngleMultiplier = _carController.steeringWheelAngleMultiplier; _originalSteeringWheelSign = Mathf.Sign(_originalSteeringWheelAngleMultiplier); - _carController.useCounterSteering = false; - _carController.useSteeringSmoother = false; + _originalCounterSteer = _carController.useCounterSteering; + _originalSteerSmoothing = _carController.useSteeringSmoother; } private void UpdateWheelState() @@ -191,27 +167,34 @@ public class SteeringWheelRoot : MonoBehaviour private void UpdateSteeringBehavior() { - UpdateSteeringMultiplier(); - + SetSteeringAssistsState(!IsWheelInactive); + if (IsWheelBeingHeld) UpdateRotationTracking(); else if (_timeWheelReleased >= 0f) HandleWheelReturn(); } - private void UpdateSteeringMultiplier() + private void SetSteeringAssistsState(bool shouldOverride) { - _carController.steeringWheelAngleMultiplier = ModSettings.EntryOverrideSteeringRange.Value + _carController.useCounterSteering = !shouldOverride && _originalCounterSteer; + _carController.useSteeringSmoother = !shouldOverride && _originalSteerSmoothing; + _carController.steeringWheelAngleMultiplier = ModSettings.EntryOverrideSteeringRange.Value && shouldOverride ? ModSettings.EntryCustomSteeringRange.Value * _originalSteeringWheelSign / _carController.steerAngle : _originalSteeringWheelAngleMultiplier; } - + private void HandleWheelReturn() { var timeSinceRelease = Time.time - _timeWheelReleased; - if (timeSinceRelease < RETURN_TO_CENTER_DURATION) + + if (timeSinceRelease < RETURN_START_DELAY) + return; + + var returnTime = timeSinceRelease - RETURN_START_DELAY; + if (returnTime < RETURN_TO_CENTER_DURATION) { - var t = timeSinceRelease / RETURN_TO_CENTER_DURATION; + var t = returnTime / RETURN_TO_CENTER_DURATION; _averageAngle = Mathf.Lerp(_averageAngle, 0f, t); for (var i = 0; i < _totalAngles.Count; i++) @@ -267,7 +250,7 @@ public class SteeringWheelRoot : MonoBehaviour Vector3 trackingAxis = GetSteeringWheelLocalAxis(); UpdateTransformAngles(trackingAxis); - UpdateAverageAngle(); + _averageAngle = CalculateAverageAngle(_trackedTransforms, _totalAngles); } private void UpdateTransformAngles(Vector3 trackingAxis) @@ -293,20 +276,19 @@ public class SteeringWheelRoot : MonoBehaviour } } - private void UpdateAverageAngle() + private static float CalculateAverageAngle(List transforms, List angles) { - var sumAngles = 0f; + var sum = 0f; var validTransforms = 0; - - for (var i = 0; i < _trackedTransforms.Count; i++) + + for (var i = 0; i < transforms.Count; i++) { - if (_trackedTransforms[i] == null) continue; - sumAngles += _totalAngles[i]; + if (transforms[i] == null) continue; + sum += angles[i]; validTransforms++; } - if (validTransforms > 0) - _averageAngle = sumAngles / validTransforms; + return validTransforms > 0 ? sum / validTransforms : 0f; } #endregion Private Methods diff --git a/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Util/BoneVertexBoundsUtility.cs b/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Util/BoneVertexBoundsUtility.cs index 093620c..f55f241 100644 --- a/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Util/BoneVertexBoundsUtility.cs +++ b/RCCVirtualSteeringWheel/RCCVirtualSteeringWheel/Util/BoneVertexBoundsUtility.cs @@ -52,7 +52,7 @@ public class BoneVertexBoundsUtility : MonoBehaviour /// Calculates the bounds of a transform based on: /// - Children Renderers /// - Skinned Mesh Weights - /// - Constrained Child Renderers & Skinned Mesh Weights + /// - Constrained Child Renderers & Skinned Mesh Weights (thanks Fearless) /// public static void CalculateBoneWeightedBounds(Transform bone, float weightThreshold, BoundsCalculationFlags flags, Action onComplete) => Instance.StartCoroutine(Instance.CalculateBoundsCoroutine(bone, weightThreshold, flags, onComplete)); diff --git a/RCCVirtualSteeringWheel/README.md b/RCCVirtualSteeringWheel/README.md index b396266..8d9f529 100644 --- a/RCCVirtualSteeringWheel/README.md +++ b/RCCVirtualSteeringWheel/README.md @@ -1,6 +1,6 @@ # RCCVirtualSteeringWheel -Experiment with making rigged RCC vehicle steering wheels work for VR steering input. +Allows you to physically grab rigged RCC steering wheels in VR to provide steering input. No explicit setup required other than defining the Steering Wheel transform within the RCC component. --- @@ -11,5 +11,4 @@ https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games > Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use. -> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive. -~~~~ \ No newline at end of file +> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.~~~~ \ No newline at end of file diff --git a/RCCVirtualSteeringWheel/format.json b/RCCVirtualSteeringWheel/format.json index 480d0fb..3f0654c 100644 --- a/RCCVirtualSteeringWheel/format.json +++ b/RCCVirtualSteeringWheel/format.json @@ -1,23 +1,23 @@ { "_id": -1, - "name": "LegacyContentMitigation", - "modversion": "1.0.1", + "name": "RCCVirtualSteeringWheel", + "modversion": "1.0.0", "gameversion": "2024r177", "loaderversion": "0.6.1", "modtype": "Mod", - "author": "Exterrata, NotAKidoS", - "description": "Experimental mod that manually renders both VR eyes separately while in Legacy Worlds.\n\nThe mod will automatically kick-in when loading NonSpi Worlds & prevent Shader Replacement for all content while active. You can also manually toggle it within the BTKUI Misc tab for experimenting.\n\n-# There is an obvious performance penalty with rendering the world 2x & toggling the head hiding per eye, so enabling the mod outside of Legacy Worlds is not recommended.", + "author": "NotAKidoS", + "description": "Allows you to physically grab rigged RCC steering wheels in VR to provide steering input. No explicit setup required other than defining the Steering Wheel transform within the RCC component.\n", "searchtags": [ - "legacy", - "content", - "spi", - "shaders" + "rcc", + "steering", + "vehicle", + "car" ], "requirements": [ "BTKUILib" ], - "downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r44/LegacyContentMitigation.dll", - "sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/LegacyContentMitigation/", + "downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r44/RCCVirtualSteeringWheel.dll", + "sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/RCCVirtualSteeringWheel/", "changelog": "- Initial release", "embedcolor": "#f61963" } \ No newline at end of file