RCCVirtualSteeringWheel: tuning & prepare for release

This commit is contained in:
NotAKidoS 2025-01-07 13:40:32 -06:00
parent 5d77eb61a5
commit 1282b2ca48
5 changed files with 57 additions and 70 deletions

View file

@ -1,12 +1,16 @@
using ABI_RC.Core.InteractionSystem; using ABI_RC.Core.InteractionSystem;
using ABI_RC.Core.InteractionSystem.Base; using ABI_RC.Core.InteractionSystem.Base;
using ABI_RC.Core.Savior;
using UnityEngine; using UnityEngine;
namespace NAK.RCCVirtualSteeringWheel; namespace NAK.RCCVirtualSteeringWheel;
public class SteeringWheelPickup : Pickupable public class SteeringWheelPickup : Pickupable
{ {
#region Public Properties internal SteeringWheelRoot root;
#region Pickupable Properties
public override bool DisallowTheft => true; public override bool DisallowTheft => true;
public override float MaxGrabDistance => 0.8f; public override float MaxGrabDistance => 0.8f;
public override float MaxPushDistance => 0f; public override float MaxPushDistance => 0f;
@ -14,11 +18,12 @@ public class SteeringWheelPickup : Pickupable
public override bool IsObjectRotationAllowed => false; public override bool IsObjectRotationAllowed => false;
public override bool IsObjectPushPullAllowed => false; public override bool IsObjectPushPullAllowed => false;
public override bool IsObjectUseAllowed => false; public override bool IsObjectUseAllowed => false;
public override bool CanPickup => IsPickupable && !IsPickedUp; public override bool CanPickup => IsPickupable && !IsPickedUp && MetaPort.Instance.isUsingVr;
internal SteeringWheelRoot root;
#endregion #endregion Pickupable Properties
#region Public Methods #region Pickupable Methods
public override void OnUseDown(InteractionContext context) { } public override void OnUseDown(InteractionContext context) { }
public override void OnUseUp(InteractionContext context) { } public override void OnUseUp(InteractionContext context) { }
public override void OnFlingTowardsTarget(Vector3 target) { } public override void OnFlingTowardsTarget(Vector3 target) { }
@ -32,5 +37,6 @@ public class SteeringWheelPickup : Pickupable
if (ControllerRay?.transform != null) if (ControllerRay?.transform != null)
root.StopTrackingTransform(ControllerRay.transform); root.StopTrackingTransform(ControllerRay.transform);
} }
#endregion
#endregion Pickupable Methods
} }

View file

@ -65,6 +65,7 @@ public class SteeringWheelRoot : MonoBehaviour
#region Public Properties #region Public Properties
private bool IsWheelBeingHeld => _pickups[0].IsPickedUp || _pickups[1].IsPickedUp; private bool IsWheelBeingHeld => _pickups[0].IsPickedUp || _pickups[1].IsPickedUp;
private bool IsWheelInactive => !IsWheelBeingHeld && _averageAngle == 0f;
#endregion Public Properties #endregion Public Properties
@ -75,6 +76,8 @@ public class SteeringWheelRoot : MonoBehaviour
private float _originalSteeringWheelAngleMultiplier; private float _originalSteeringWheelAngleMultiplier;
private float _originalSteeringWheelSign; private float _originalSteeringWheelSign;
private bool _originalCounterSteer;
private bool _originalSteerSmoothing;
private readonly List<Transform> _trackedTransforms = new(); private readonly List<Transform> _trackedTransforms = new();
private readonly List<Vector3> _lastPositions = new(); private readonly List<Vector3> _lastPositions = new();
@ -84,6 +87,7 @@ public class SteeringWheelRoot : MonoBehaviour
private float _averageAngle; private float _averageAngle;
private float _timeWheelReleased = -1f; private float _timeWheelReleased = -1f;
private const float RETURN_TO_CENTER_DURATION = 2f; private const float RETURN_TO_CENTER_DURATION = 2f;
private const float RETURN_START_DELAY = 0.1f;
#endregion Private Variables #endregion Private Variables
@ -115,21 +119,7 @@ public class SteeringWheelRoot : MonoBehaviour
{ {
if (trans == null) return; if (trans == null) return;
var currentAngle = 0f; var currentAngle = _isTracking ? CalculateAverageAngle(_trackedTransforms, _totalAngles) : 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;
}
_trackedTransforms.Add(trans); _trackedTransforms.Add(trans);
_lastPositions.Add(GetLocalPositionWithoutRotation(transform.position)); _lastPositions.Add(GetLocalPositionWithoutRotation(transform.position));
@ -142,7 +132,7 @@ public class SteeringWheelRoot : MonoBehaviour
var index = _trackedTransforms.IndexOf(trans); var index = _trackedTransforms.IndexOf(trans);
if (index == -1) return; if (index == -1) return;
var currentAverage = CalculateCurrentAverage(); var currentAverage = CalculateAverageAngle(_trackedTransforms, _totalAngles);
_trackedTransforms.RemoveAt(index); _trackedTransforms.RemoveAt(index);
_lastPositions.RemoveAt(index); _lastPositions.RemoveAt(index);
_totalAngles.RemoveAt(index); _totalAngles.RemoveAt(index);
@ -153,21 +143,7 @@ public class SteeringWheelRoot : MonoBehaviour
for (var i = 0; i < _totalAngles.Count; i++) for (var i = 0; i < _totalAngles.Count; i++)
_totalAngles[i] = currentAverage; _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 #endregion Public Methods
#region Private Methods #region Private Methods
@ -176,8 +152,8 @@ public class SteeringWheelRoot : MonoBehaviour
{ {
_originalSteeringWheelAngleMultiplier = _carController.steeringWheelAngleMultiplier; _originalSteeringWheelAngleMultiplier = _carController.steeringWheelAngleMultiplier;
_originalSteeringWheelSign = Mathf.Sign(_originalSteeringWheelAngleMultiplier); _originalSteeringWheelSign = Mathf.Sign(_originalSteeringWheelAngleMultiplier);
_carController.useCounterSteering = false; _originalCounterSteer = _carController.useCounterSteering;
_carController.useSteeringSmoother = false; _originalSteerSmoothing = _carController.useSteeringSmoother;
} }
private void UpdateWheelState() private void UpdateWheelState()
@ -191,27 +167,34 @@ public class SteeringWheelRoot : MonoBehaviour
private void UpdateSteeringBehavior() private void UpdateSteeringBehavior()
{ {
UpdateSteeringMultiplier(); SetSteeringAssistsState(!IsWheelInactive);
if (IsWheelBeingHeld) if (IsWheelBeingHeld)
UpdateRotationTracking(); UpdateRotationTracking();
else if (_timeWheelReleased >= 0f) else if (_timeWheelReleased >= 0f)
HandleWheelReturn(); 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 ? ModSettings.EntryCustomSteeringRange.Value * _originalSteeringWheelSign / _carController.steerAngle
: _originalSteeringWheelAngleMultiplier; : _originalSteeringWheelAngleMultiplier;
} }
private void HandleWheelReturn() private void HandleWheelReturn()
{ {
var timeSinceRelease = Time.time - _timeWheelReleased; 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); _averageAngle = Mathf.Lerp(_averageAngle, 0f, t);
for (var i = 0; i < _totalAngles.Count; i++) for (var i = 0; i < _totalAngles.Count; i++)
@ -267,7 +250,7 @@ public class SteeringWheelRoot : MonoBehaviour
Vector3 trackingAxis = GetSteeringWheelLocalAxis(); Vector3 trackingAxis = GetSteeringWheelLocalAxis();
UpdateTransformAngles(trackingAxis); UpdateTransformAngles(trackingAxis);
UpdateAverageAngle(); _averageAngle = CalculateAverageAngle(_trackedTransforms, _totalAngles);
} }
private void UpdateTransformAngles(Vector3 trackingAxis) private void UpdateTransformAngles(Vector3 trackingAxis)
@ -293,20 +276,19 @@ public class SteeringWheelRoot : MonoBehaviour
} }
} }
private void UpdateAverageAngle() private static float CalculateAverageAngle(List<Transform> transforms, List<float> angles)
{ {
var sumAngles = 0f; var sum = 0f;
var validTransforms = 0; var validTransforms = 0;
for (var i = 0; i < _trackedTransforms.Count; i++) for (var i = 0; i < transforms.Count; i++)
{ {
if (_trackedTransforms[i] == null) continue; if (transforms[i] == null) continue;
sumAngles += _totalAngles[i]; sum += angles[i];
validTransforms++; validTransforms++;
} }
if (validTransforms > 0) return validTransforms > 0 ? sum / validTransforms : 0f;
_averageAngle = sumAngles / validTransforms;
} }
#endregion Private Methods #endregion Private Methods

View file

@ -52,7 +52,7 @@ public class BoneVertexBoundsUtility : MonoBehaviour
/// Calculates the bounds of a transform based on: /// Calculates the bounds of a transform based on:
/// - Children Renderers /// - Children Renderers
/// - Skinned Mesh Weights /// - Skinned Mesh Weights
/// - Constrained Child Renderers & Skinned Mesh Weights /// - Constrained Child Renderers & Skinned Mesh Weights (thanks Fearless)
/// </summary> /// </summary>
public static void CalculateBoneWeightedBounds(Transform bone, float weightThreshold, BoundsCalculationFlags flags, Action<BoundsResult> onComplete) public static void CalculateBoneWeightedBounds(Transform bone, float weightThreshold, BoundsCalculationFlags flags, Action<BoundsResult> onComplete)
=> Instance.StartCoroutine(Instance.CalculateBoundsCoroutine(bone, weightThreshold, flags, onComplete)); => Instance.StartCoroutine(Instance.CalculateBoundsCoroutine(bone, weightThreshold, flags, onComplete));

View file

@ -1,6 +1,6 @@
# RCCVirtualSteeringWheel # 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. > 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. > To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.~~~~
~~~~

View file

@ -1,23 +1,23 @@
{ {
"_id": -1, "_id": -1,
"name": "LegacyContentMitigation", "name": "RCCVirtualSteeringWheel",
"modversion": "1.0.1", "modversion": "1.0.0",
"gameversion": "2024r177", "gameversion": "2024r177",
"loaderversion": "0.6.1", "loaderversion": "0.6.1",
"modtype": "Mod", "modtype": "Mod",
"author": "Exterrata, NotAKidoS", "author": "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.", "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": [ "searchtags": [
"legacy", "rcc",
"content", "steering",
"spi", "vehicle",
"shaders" "car"
], ],
"requirements": [ "requirements": [
"BTKUILib" "BTKUILib"
], ],
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r44/LegacyContentMitigation.dll", "downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r44/RCCVirtualSteeringWheel.dll",
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/LegacyContentMitigation/", "sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/RCCVirtualSteeringWheel/",
"changelog": "- Initial release", "changelog": "- Initial release",
"embedcolor": "#f61963" "embedcolor": "#f61963"
} }