velox/Code/Car/VeloXCar.Drift.cs
2025-12-03 15:17:36 +07:00

76 lines
1.7 KiB
C#

using Sandbox;
using Sandbox.Audio;
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 )
{
var avgslip = 0f;
foreach ( var item in Wheels )
avgslip += item.NormalizedLongitudinalSlip + item.NormalizedLateralSlip;
float mul = Math.Clamp( avgslip, 0, 2 );
targetVolume = mul;
targetPitch = 0.75f + 0.25f * mul;
if ( mul > 0.1f && !_skidHandle.IsValid() )
{
_skidHandle = Sound.PlayFile( SkidSound );
_skidHandle.TargetMixer = Mixer.Default;
}
if ( !_skidHandle.IsValid() )
return;
_skidHandle.Pitch += (targetPitch - _skidHandle.Pitch) * dt * 5f;
_skidHandle.Volume += (targetVolume - _skidHandle.Volume) * dt * 10f;
_skidHandle.Position = WorldPosition;
}
}