mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 06:19:22 +00:00
RCCVirtualSteeringWheel: tuning & prepare for release
This commit is contained in:
parent
5d77eb61a5
commit
1282b2ca48
5 changed files with 57 additions and 70 deletions
|
@ -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
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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.~~~~
|
||||||
~~~~
|
|
|
@ -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"
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue