Code/Vehicle/Powertrain/WheelPowertrain.cs
using Sandbox;
using Meteor.VehicleTool.Vehicle.Wheel;
using System;
namespace Meteor.VehicleTool.Vehicle.Powertrain;
public partial class WheelPowertrain : PowertrainComponent
{
protected override void OnAwake()
{
base.OnAwake();
Name ??= Wheel.ToString();
}
[Property] public WheelCollider Wheel { get; set; }
protected override void OnStart()
{
_initialRollingResistance = Wheel.RollingResistanceTorque;
_initialWheelInertia = Wheel.Inertia;
}
private float _initialRollingResistance;
private float _initialWheelInertia;
/// <summary>
/// Adds brake torque to the wheel on top of the existing torque. Value is clamped to max brake torque.
/// </summary>
public void AddBrakeTorque( float torque )
{
Wheel.BrakeTorque = Math.Clamp( Wheel.BrakeTorque, 0, Controller.MaxBrakeTorque ) + Math.Max( torque, 0 );
}
public override float QueryAngularVelocity( float angularVelocity, float dt )
{
InputAngularVelocity = OutputAngularVelocity = Wheel.AngularVelocity;
return OutputAngularVelocity;
}
public override float QueryInertia()
{
// Calculate the base inertia of the wheel and scale it by the inverse of the dt.
float dtScale = Math.Clamp( Time.Delta, 0.01f, 0.05f ) / 0.005f;
float radius = Wheel.Radius.InchToMeter();
return 0.5f * Wheel.Mass * radius * radius * dtScale;
}
public void ApplyRollingResistanceMultiplier( float multiplier )
{
Wheel.RollingResistanceTorque = _initialRollingResistance * multiplier;
}
public override float ForwardStep( float torque, float inertiaSum, float dt )
{
InputTorque = torque;
InputInertia = inertiaSum;
OutputTorque = InputTorque;
OutputInertia = _initialWheelInertia + inertiaSum;
Wheel.MotorTorque = OutputTorque;
Wheel.Inertia = OutputInertia;
Wheel.AutoSimulate = false;
Wheel.PhysUpdate( dt );
return Math.Abs( Wheel.CounterTorque );
}
}