using Sandbox; using System; using System.Threading; 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 SteerConeMaxSpeed { get; set; } = 1800; [Property, Feature( "Steer" )] public float SteerConeMaxAngle { get; set; } = 0.25f; [Property, Feature( "Steer" )] public float SteerConeChangeRate { get; set; } = 8; [Property, Feature( "Steer" )] public float CounterSteer { get; set; } = 0.1f; [Property, Feature( "Steer" )] public float MaxSteerAngle { get; set; } = 35f; [Sync] public float Steering { get; private set; } private float jTurnMultiplier; private float inputSteer; private void UpdateSteering( float dt ) { var inputSteer = Input.AnalogMove.y; var absInputSteer = Math.Abs( inputSteer ); var sideSlip = Math.Clamp( avgSideSlip, -1, 1 ); var steerConeFactor = Math.Clamp( TotalSpeed / SteerConeMaxSpeed, 0, 1 ); var steerCone = 1 - steerConeFactor * (1 - SteerConeMaxAngle); steerCone = Math.Clamp( steerCone, Math.Abs( sideSlip ), 1 ); inputSteer = ExpDecay( this.inputSteer, inputSteer * steerCone, SteerConeChangeRate, dt ); this.inputSteer = inputSteer; var counterSteer = sideSlip * steerConeFactor * (1 - absInputSteer); counterSteer = Math.Clamp( counterSteer, -1, 1 ) * CounterSteer; inputSteer = Math.Clamp( inputSteer + counterSteer, -1, 1 ); Steering = inputSteer; SteerAngle = new( 0, -inputSteer * MaxSteerAngle, 0 ); if ( ForwardSpeed < -100 ) jTurnMultiplier = 0.5f; else jTurnMultiplier = ExpDecay( jTurnMultiplier, 1, 2, dt ); } }