velox/Code/Car/VeloXCar.Steering.cs
2025-11-06 12:13:30 +07:00

52 lines
1.6 KiB
C#

using Sandbox;
using System;
using VeloX.Utils;
namespace VeloX;
public partial class VeloXCar
{
public static float ExpDecay( float a, float b, float decay, float dt ) => b + (a - b) * MathF.Exp( -decay * dt );
[Property, Feature( "Steer" )] public float MaxSteerAngle { get; set; } = 40f;
[ConVar( "steer_return_speed" )]
[Property] public static float SteerReturnSpeed { get; set; } = 6f;
[ConVar( "steer_speed" )]
public static float SteerInputResponse { get; set; } = 3f;
[ConVar( "assist_mult" )]
public static float MaxSteerAngleMultiplier { get; set; } = 1f;
public int CarDirection { get { return ForwardSpeed < 1 ? 0 : (VelocityAngle < 90 && VelocityAngle > -90 ? 1 : -1); } }
public float VelocityAngle { get; private set; }
[Sync] public float Steering { get; private set; }
private float currentSteerAngle;
private float inputSteer;
private void UpdateSteering( float dt )
{
inputSteer = Input.AnalogMove.y;
float targetSteerAngle = inputSteer * MaxSteerAngle;
if ( !Input.Down( "Jump" ) )
targetSteerAngle *= Math.Clamp( 1 - Math.Clamp( TotalSpeed / 3000, 0.01f, 0.9f ), -1, 1 );
VelocityAngle = -Body.Velocity.SignedAngle( WorldRotation.Forward, WorldRotation.Up );
float targetAngle = 0;
if ( TotalSpeed > 150 && CarDirection > 0 && IsOnGround )
targetAngle = VelocityAngle * MaxSteerAngleMultiplier;
float lerpSpeed = Math.Abs( inputSteer ) < 0.1f ? SteerReturnSpeed : SteerInputResponse;
currentSteerAngle = ExpDecay( currentSteerAngle, targetSteerAngle, lerpSpeed, Time.Delta );
Steering = currentSteerAngle + targetAngle;
SteerAngle = new( 0, Math.Clamp( Steering, -MaxSteerAngle, MaxSteerAngle ), 0 );
}
}