NWH Wheel Controller 3D
Search Results for

    Show / Hide Table of Contents

    Class StandardFriction

    Default friction implementation using Pacejka-based curves for tire force calculations. Uses a semi-implicit Newton-Raphson solver for stable equilibrium convergence in 2-3 iterations. Includes static friction anchoring with critical damping for low-speed stability.

    Inheritance
    object
    Object
    Component
    Behaviour
    MonoBehaviour
    FrictionBase
    StandardFriction
    Inherited Members
    FrictionBase.isStaticActive
    FrictionBase.brokeStaticThisFrame
    FrictionBase.staticReEntryCooldown
    Namespace: NWH.WheelController3D
    Assembly: NWH.WheelController.dll
    Syntax
    [DisallowMultipleComponent]
    public class StandardFriction : FrictionBase

    Fields

    | Edit this page View Source

    _prevForceX

    Previous-substep longitudinal force, filtered by relaxation length (N).

    Declaration
    [NonSerialized]
    public float _prevForceX
    Field Value
    Type Description
    float
    | Edit this page View Source

    _prevForceY

    Previous-substep lateral force, filtered by relaxation length (N).

    Declaration
    [NonSerialized]
    public float _prevForceY
    Field Value
    Type Description
    float
    | Edit this page View Source

    _staticFrictionPoint

    World-space static friction anchor used when the contact surface has no transform to track.

    Declaration
    [NonSerialized]
    public Vector3 _staticFrictionPoint
    Field Value
    Type Description
    Vector3
    | Edit this page View Source

    absPulseInterval

    ABS pump cycle (s): the brake modifier is sampled then held this long. 0 = resample every substep.

    Declaration
    [Range(0, 0.2)]
    [Tooltip("ABS pump cycle interval (s). Brake modifier is sampled then held for this long, like a real pump (0.05 = 20 Hz). 0 = resample every substep.")]
    public float absPulseInterval
    Field Value
    Type Description
    float
    | Edit this page View Source

    brakeBlendThreshold

    Wheel angular-velocity threshold (rad/s) below which brake force direction is blended to avoid sign flips.

    Declaration
    [Tooltip("Angular velocity threshold for brake direction blending (rad/s).")]
    public float brakeBlendThreshold
    Field Value
    Type Description
    float
    | Edit this page View Source

    brakeLockThreshold

    Minimum brake torque (Nm) before wheel-lock handling is evaluated.

    Declaration
    [Tooltip("Minimum brake torque to trigger wheel lock checks (Nm).")]
    public float brakeLockThreshold
    Field Value
    Type Description
    float
    | Edit this page View Source

    camberGripFalloff

    Grip lost per squared degree of camber away from optimal. 0 = off; keep 0 for motorcycles.

    Declaration
    [Range(0, 0.05)]
    [Tooltip("Grip lost per squared degree of camber away from optimal. 0 = off. Keep 0 for motorcycles.")]
    public float camberGripFalloff
    Field Value
    Type Description
    float
    | Edit this page View Source

    ellipseLateralPriority

    On ellipse overflow at very low speed / brake-lock, how much lateral force is preserved before longitudinal. 0 = symmetric clamp; 1 = lateral keeps full capacity, longitudinal takes the remainder. Keeps a locked wheel (handbrake) holding sideways on a cross-slope instead of trading lateral grip for brake reaction.

    Declaration
    [Range(0, 1)]
    [Tooltip("On ellipse overflow at low speed / brake-lock, how much lateral grip is preserved before longitudinal. 0 = symmetric (default model). 1 = full lateral priority. Helps a locked wheel hold across a slope.")]
    public float ellipseLateralPriority
    Field Value
    Type Description
    float
    | Edit this page View Source

    frictionEllipticity

    Friction-ellipse shape for combined slip. 1 = circle; above 1 degrades lateral grip faster under combined load.

    Declaration
    [Range(0.5, 2)]
    [Tooltip("Friction ellipse shape. 1.0 = circle (default). >1.0 = lateral forces degrade faster under combined loading (realistic). <1.0 = more forgiving.")]
    public float frictionEllipticity
    Field Value
    Type Description
    float
    | Edit this page View Source

    grip

    Per-axis friction force multiplier (X = longitudinal, Y = lateral). Scales the Y of the friction curve.

    Declaration
    [Tooltip("Multiplies the calculated friction force (Y-axis of curve). X=Longitudinal, Y=Lateral.")]
    public Vector2 grip
    Field Value
    Type Description
    Vector2
    | Edit this page View Source

    lateralLowSpeedMinScale

    Minimum lateral slip scale at the static/dynamic transition. 1 = no low-speed lateral trim (recovers grip at the handoff); lower trims lateral force there. Lateral is not in the Newton solver, so trimming is optional.

    Declaration
    [Range(0, 1)]
    [Tooltip("Minimum lateral slip scale at the static/dynamic transition. 1.0 = no trim (recovers grip at handoff). Lower trims lateral force at the transition.")]
    public float lateralLowSpeedMinScale
    Field Value
    Type Description
    float
    | Edit this page View Source

    loadPeakSlipShift

    How much the slip at peak grip grows with load. Loaded tires peak later and softer; 0 = load-independent.

    Declaration
    [Range(0, 1)]
    [Tooltip("How much the slip needed for peak grip grows with load. Loaded tires peak later and respond softer, light tires sharper. 0 = off.")]
    public float loadPeakSlipShift
    Field Value
    Type Description
    float
    | Edit this page View Source

    loadSensitivity

    How grip scales with load, per axis. 1 = linear; below 1 gives diminishing returns with load (realistic).

    Declaration
    [Tooltip("How much friction increases with load. 1.0 = Linear. <1.0 = Diminishing returns (realistic).")]
    public Vector2 loadSensitivity
    Field Value
    Type Description
    Vector2
    | Edit this page View Source

    lowSpeedLateralGripFloor

    Closes the static→dynamic lateral grip cliff: at low slide speed the lateral force is blended toward the slope-hold force (up to this fraction of available grip) immediately, instead of waiting for slip to build over the slide. 0 = off (original ramp). Fades out above the static-entry speed.

    Declaration
    [Range(0, 1)]
    [Tooltip("At low slide speed, build lateral force toward the slope-hold force up to this fraction of grip immediately, instead of waiting for slip to develop. Closes the static->dynamic grip cliff. 0 = off.")]
    public float lowSpeedLateralGripFloor
    Field Value
    Type Description
    float
    | Edit this page View Source

    lowSpeedLateralSlipAtPeak

    At low slide speed, hold the lateral operating point at the Pacejka peak (clamp lateral slip to peak slip) instead of letting the slip-denominator floor push it onto the falling side. Fades out above the entry speed.

    Declaration
    [Tooltip("At low slide speed, keep lateral slip at the curve peak (max grip) instead of the falling side. Fades out above the static-entry speed.")]
    public bool lowSpeedLateralSlipAtPeak
    Field Value
    Type Description
    bool
    | Edit this page View Source

    lowSpeedSlipMinScale

    Minimum slip scale at the static/dynamic transition. Lower trims force there to damp oscillation.

    Declaration
    [Tooltip("Minimum slip scale at static/dynamic transition. Lower values reduce force at transition to prevent oscillation.")]
    [Range(0, 1)]
    public float lowSpeedSlipMinScale
    Field Value
    Type Description
    float
    | Edit this page View Source

    lowSpeedSlipRampEnd

    Speed (m/s) at which slip scaling reaches full; below it slip is scaled down to cut low-speed sensitivity.

    Declaration
    [Tooltip("Speed (m/s) at which slip scaling reaches full (no reduction). Below this, slip is scaled down to reduce sensitivity.")]
    [Range(0.5, 2)]
    public float lowSpeedSlipRampEnd
    Field Value
    Type Description
    float
    | Edit this page View Source

    lowSpeedSurfaceThreshold

    Tire-surface speed (m/s) below which the wheel is treated as rotationally stopped.

    Declaration
    [Tooltip("Linear velocity (m/s) at the tire surface below which the wheel is considered rotationally stopped.")]
    public float lowSpeedSurfaceThreshold
    Field Value
    Type Description
    float
    | Edit this page View Source

    maxSolverIterations

    Upper bound on Newton-Raphson iterations per solve.

    Declaration
    [Tooltip("Maximum Newton-Raphson iterations per frame.")]
    [Range(1, 30)]
    public int maxSolverIterations
    Field Value
    Type Description
    int
    | Edit this page View Source

    mechanicalTrailCoefficient

    Mechanical (caster) trail as a fraction of wheel radius. Persists at high slip, keeping steering weight in slides.

    Declaration
    [Tooltip("Mechanical (caster) trail as fraction of wheel radius. Does not collapse at high slip, keeping steering weight in slides.")]
    [Range(0, 0.15)]
    public float mechanicalTrailCoefficient
    Field Value
    Type Description
    float
    | Edit this page View Source

    optimalCamber

    Camber angle (deg) at which grip peaks. Typically 0 to -2.

    Declaration
    [Tooltip("Camber angle (deg) at which grip is highest. Usually 0 to -2.")]
    public float optimalCamber
    Field Value
    Type Description
    float
    | Edit this page View Source

    pneumaticTrailCoefficient

    Pneumatic trail as a fraction of wheel radius; sets the self-aligning torque arm.

    Declaration
    [Tooltip("Pneumatic trail coefficient as fraction of wheel radius.")]
    [Range(0.02, 0.15)]
    public float pneumaticTrailCoefficient
    Field Value
    Type Description
    float
    | Edit this page View Source

    relaxationLengthX

    Longitudinal relaxation length (m): distance the tire must roll to build full longitudinal force. Smooths grip onset.

    Declaration
    [Tooltip("Longitudinal relaxation length (m). Distance tire must travel to fully develop longitudinal force. Smooths grip transitions.")]
    [Range(0.01, 0.3)]
    public float relaxationLengthX
    Field Value
    Type Description
    float
    | Edit this page View Source

    relaxationLengthY

    Lateral relaxation length (m): distance the tire must roll to build full lateral force. Typically ~2x longitudinal.

    Declaration
    [Tooltip("Lateral relaxation length (m). Distance tire must travel to fully develop lateral force. Typically 2x longitudinal.")]
    [Range(0.01, 0.6)]
    public float relaxationLengthY
    Field Value
    Type Description
    float
    | Edit this page View Source

    slipDenominatorFloor

    Regularization floor for the slip denominator (sqrt(v^2 + eps^2)); sets low-speed friction sensitivity.

    Declaration
    [Tooltip("Regularization epsilon for slip denominator. Controls low-speed friction sensitivity via sqrt(v^2 + eps^2).")]
    [Range(0.1, 2)]
    public float slipDenominatorFloor
    Field Value
    Type Description
    float
    | Edit this page View Source

    solverConvergenceThreshold

    Newton-Raphson convergence tolerance for the friction solver.

    Declaration
    [Tooltip("Newton-Raphson convergence threshold for friction solver.")]
    public float solverConvergenceThreshold
    Field Value
    Type Description
    float
    | Edit this page View Source

    staticBreakThreshold

    Demand, as a multiple of available grip, needed to break static friction. Models static-over-kinetic stiction.

    Declaration
    [Range(1, 3)]
    [Tooltip("The multiplier of max grip required to break static friction.")]
    public float staticBreakThreshold
    Field Value
    Type Description
    float
    | Edit this page View Source

    staticDriveBreakMode

    How drive input releases static friction. InputGated: any net drive breaks the hold (original). DemandGated: while the rig is at rest AND a brake/handbrake is applied, drive does NOT break static, so the vehicle (and unbraked driven wheels) hold still under handbrake+throttle on a slope. Releasing the brake or moving reverts to the input-gated break so the vehicle launches normally.

    Declaration
    [Tooltip("How throttle releases static friction. DemandGated keeps the hold while stationary AND braked (handbrake+throttle holds on a slope). InputGated = original behaviour (any drive breaks the hold).")]
    public StaticDriveBreakMode staticDriveBreakMode
    Field Value
    Type Description
    StaticDriveBreakMode
    | Edit this page View Source

    staticFrictionAnchorRelaxRate

    Declaration
    [Range(0, 0.2)]
    [Tooltip("Per-substep rate at which the static anchor relaxes toward the current tread position when the vehicle has settled on near-flat ground. Eliminates residual spring forces from initial settle-in where 4 wheel anchors were captured at slightly different poses. 0 disables. Active only when near-stationary AND slope-demand is small, so slope-holding is not compromised.")]
    public float staticFrictionAnchorRelaxRate
    Field Value
    Type Description
    float
    | Edit this page View Source

    staticFrictionCooldownFrames

    Substeps (not FixedUpdate frames) to wait before static friction may re-engage after it breaks.

    Declaration
    [Tooltip("Substeps (not FixedUpdate frames) to wait before static friction can re-engage. 1 FixedUpdate is typically 4-6 substeps at default WheelControllerManager rates.")]
    public int staticFrictionCooldownFrames
    Field Value
    Type Description
    int
    | Edit this page View Source

    staticFrictionDamping

    Static-anchor damping ratio. 1 = critical (no overshoot); lower if springy, higher if sluggish.

    Declaration
    [Range(0, 2)]
    [Tooltip("Damping ratio. 1.0 = Critical Damping (No Overshoot). Lower <1.0 if slightly springy, Raise >1.0 if sluggish.")]
    public float staticFrictionDamping
    Field Value
    Type Description
    float
    | Edit this page View Source

    staticFrictionEnabled

    Master toggle for static friction. When off the holding force is bypassed and only dynamic friction is used (debug).

    Declaration
    [Tooltip("When disabled, static friction is bypassed and only dynamic friction is used. For debugging.")]
    public bool staticFrictionEnabled
    Field Value
    Type Description
    bool
    | Edit this page View Source

    staticFrictionHysteresis

    Hysteresis: multiplies the speed threshold for exiting static mode so entry and exit do not chatter.

    Declaration
    [Range(1, 3)]
    [Tooltip("Multiplier for the speed threshold to EXIT static mode (Hysteresis).")]
    public float staticFrictionHysteresis
    Field Value
    Type Description
    float
    | Edit this page View Source

    staticFrictionSpeedThreshold

    Surface speed (m/s) below which the tire tries to enter static (holding) mode.

    Declaration
    [Range(0.05, 1)]
    [Tooltip("Velocity (m/s) under which the tire attempts to enter 'Static' mode.")]
    public float staticFrictionSpeedThreshold
    Field Value
    Type Description
    float
    | Edit this page View Source

    staticFrictionStrength

    Master scale for the low-speed static holding force. 0 = off, 1 = full static friction.

    Declaration
    [Range(0, 1)]
    [Tooltip("Master switch for the static holding force. 1.0 = Full Static Friction.")]
    public float staticFrictionStrength
    Field Value
    Type Description
    float
    | Edit this page View Source

    staticLateralStiffness

    Lateral (sidewall) static spring stiffness, as a multiple of the longitudinal stiffness.

    Declaration
    [Tooltip("Lateral Stiffness (Sidewall). Multiplier of Longitudinal.")]
    [Range(0.1, 1)]
    public float staticLateralStiffness
    Field Value
    Type Description
    float
    | Edit this page View Source

    staticLongitudinalStiffness

    Longitudinal static spring stiffness (braking hold). Effective stiffness = vehicle mass * this.

    Declaration
    [Tooltip("Longitudinal Stiffness (Brakes). Stiffness = Mass * this.")]
    public float staticLongitudinalStiffness
    Field Value
    Type Description
    float
    | Edit this page View Source

    stiffness

    Per-axis slip stiffness (X = longitudinal, Y = lateral). Scales the slip input; higher = sharper, more responsive tire.

    Declaration
    [Tooltip("Multiplies the input slip (X-axis of curve). Higher values make tires more responsive/stiff.")]
    public Vector2 stiffness
    Field Value
    Type Description
    Vector2
    | Edit this page View Source

    unpoweredBreakThreshold

    Demand (as a multiple of grip) needed to break static on an unpowered, unbraked wheel pushed by its neighbours (e.g. trailer wheels). Lower than the powered break threshold; raise toward it for stronger trailer/cross-slope hold.

    Declaration
    [Range(0.5, 3)]
    [Tooltip("Demand multiplier to break static on an unpowered, unbraked wheel pushed by other wheels (e.g. a trailer). Raise toward Break Threshold for stronger trailer hold on slopes.")]
    public float unpoweredBreakThreshold
    Field Value
    Type Description
    float

    Methods

    | Edit this page View Source

    BreakStaticFriction(int, bool)

    Forces the tire to exit static friction mode. Called by WheelControllerGroup when coordinating static friction break across all wheels on a vehicle.

    Declaration
    public override void BreakStaticFriction(int cooldownFrames = 0, bool clearFilterHistory = false)
    Parameters
    Type Name Description
    int cooldownFrames

    Substeps to wait before re-entry. 0 = use the friction implementation's configured cooldown (StandardFriction.staticFrictionCooldownFrames).

    bool clearFilterHistory

    If true, also zero the relaxation-filter history so the next dynamic substep starts from a clean baseline. Use for external breaks (vehicle reset, teleport) where the prior _prev force values are no longer meaningful. Cascading breaks from CoordinateStaticFrictionBreak should keep the default (false) so the in-substep seeding done inside ProcessStaticFriction is preserved.

    Overrides
    FrictionBase.BreakStaticFriction(int, bool)
    | Edit this page View Source

    UpdateFriction(WheelController, float)

    Calculates and updates tire friction forces based on current wheel slip and load conditions. Called every physics frame (FixedUpdate) to determine longitudinal and lateral tire forces. Implementation should update wheel.angularVelocity, frictionForceMagnitude, frictionSlip, and frictionForce.

    Declaration
    public override void UpdateFriction(WheelController wc, float deltaTime)
    Parameters
    Type Name Description
    WheelController wc

    WheelController instance containing current state: slip data, load, speed, and tire properties

    float deltaTime

    Physics timestep duration in seconds (typically Time.fixedDeltaTime)

    Overrides
    FrictionBase.UpdateFriction(WheelController, float)
    Remarks

    The method should:

    1. Calculate longitudinal slip and forces (acceleration/braking)
    2. Update wheel.angularVelocity based on motor torque, brake torque, and friction
    3. Set wc.frictionForceMagnitude (X=longitudinal, Y=lateral) in Newtons
    4. Set wc.frictionSlip (X=longitudinal, Y=lateral) as normalized values
    5. Calculate wc.counterTorque for powertrain feedback

    Access current state through:

    • wc.frictionSpeed: Contact point velocity (X=forward, Y=sideways)
    • wc.load: Current vertical tire load in Newtons
    • wc.loadRating: Maximum rated tire load
    • wc.activeFrictionPreset: Current friction curve parameters
    • wc.motorTorque/brakeTorque: Applied torques
    • wc.wheel.angularVelocity: Current wheel rotation speed
    • Edit this page
    • View Source
    In this article
    Back to top Copyright © NWH - Vehicle Physics, Aerodynamics, Dynamic Water Physics