using Sandbox; using System; namespace VeloX; public partial class VeloXCar { public const float MIN_DRIFT_ANGLE = 10f; public const float MIN_DRIFT_SPEED = 10f; public const float MAX_DRIFT_ANGLE = 110f; public static readonly SoundFile SkidSound = SoundFile.Load( "sounds/tire/skid.wav" ); private SoundHandle _skidHandle; private float targetPitch; private float targetVolume; public float GetDriftAngle() { if ( !IsOnGround ) return 0; var velocity = Body.Velocity; var forward = WorldRotation.Forward; // Early exit if speed is too low if ( TotalSpeed < MIN_DRIFT_SPEED ) return 0f; // Normalize the dot product calculation float dotProduct = velocity.Normal.Dot( forward ); // Handle potential floating point precision issues float cosAngle = dotProduct; cosAngle = MathX.Clamp( cosAngle, -1f, 1f ); // Calculate angle in degrees float angle = MathF.Abs( MathX.RadianToDegree( MathF.Acos( cosAngle ) ) ); // Check if angle is within drift range if ( angle >= MIN_DRIFT_ANGLE && angle <= MAX_DRIFT_ANGLE ) return angle; return 0f; } protected virtual void UpdateDrift( float dt ) { float driftAngle = GetDriftAngle(); float mul = (driftAngle - MIN_DRIFT_ANGLE) / (90 - MIN_DRIFT_ANGLE); if ( !_skidHandle.IsValid() ) _skidHandle = Sound.PlayFile( SkidSound ); if ( !_skidHandle.IsValid() ) return; targetVolume = mul; targetPitch = 0.75f + 0.25f * mul; _skidHandle.Pitch += (targetPitch - _skidHandle.Pitch) * dt * 5f; _skidHandle.Volume += (targetVolume - _skidHandle.Volume) * dt * 10f; _skidHandle.Position = WorldPosition; } }