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

71 lines
1.6 KiB
C#

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;
}
}