NWH Vehicle Physics 2
Search Results for

    Show / Hide Table of Contents

    Class MotorcycleModule

    Specialized physics module for two-wheeled vehicle dynamics and balance control.

    Inheritance
    object
    VehicleComponent
    MotorcycleModule
    Inherited Members
    VehicleComponent.state
    VehicleComponent.vehicleController
    VehicleComponent.IsActive
    VehicleComponent.VC_Initialize(VehicleController)
    VehicleComponent.VC_SetDefaults()
    VehicleComponent.VC_LoadStateFromStateSettings()
    VehicleComponent.VC_DrawGizmos()
    VehicleComponent.UpdateLOD()
    VehicleComponent.ToggleState()
    Namespace: NWH.VehiclePhysics2.Modules.MotorcycleModule
    Assembly: NWH.VehiclePhysics2.dll
    Syntax
    [Serializable]
    public class MotorcycleModule : VehicleComponent
    Remarks

    The MotorcycleModule turns a standard VehicleController into a motorcycle by actively balancing it: steering input sets a target lean angle and a PID controller applies the roll torque needed to reach and hold it. Cornering force is produced from the lean angle and capped at tire grip. This is an active "point-and-lean" model - it does not simulate gyroscopic precession, trail/rake, or true counter-steering (the steered wheel does not move opposite to the turn). The PID stands in for the rider's active balance loop.

    Key Features: - Active lean/balance via a PID controller that applies roll torque - Speed-dependent lean angle limit and lean rate - Grip-limited cornering: lean force is capped at tire mu, so the bike runs wide / washes out at the limit - Slip-based lean compensation to reduce highsiding during slides - Visual animation support for handlebars and swingarm - Balance assistance tunable from arcade to sim feel

    Setup Requirements: - Vehicle must have exactly 2 wheels (front and rear) - Wheels should be configured in order: [0] = front, [1] = rear - No differentials needed - transmission outputs directly to rear wheel - Recommended to use narrow wheel colliders for accurate lean behavior

    PID Controller Tuning: The lean control uses a PID controller that requires tuning for each vehicle: - Proportional (P): Primary response to lean angle error (default: 4) - Integral (I): Corrects accumulated error over time (default: 5) - Derivative (D): Dampens oscillations and overshooting (default: 1) - Start with default values and adjust in Play Mode for best results

    The module balances realism with playability - while it simulates authentic motorcycle physics, the PID controller prevents frustrating tip-overs and provides stability assistance that can be tuned from arcade to simulation levels.

    For more information visit: https://nwhcoding.com/VehiclePhysics/manual/MotorcycleModule.html

    Fields

    gainDerivative

    PID controller derivative gain for lean stabilization.

    Declaration
    [Tooltip("Lean PID controller derivative gain.")]
    public float gainDerivative
    Field Value
    Type Description
    float
    Remarks

    Controls the damping response to rapid changes in lean angle. Helps prevent oscillation and overshooting during lean corrections.

    Tuning guide: - Too low (0-0.5): May oscillate or overshoot target lean - Optimal (0.5-2): Smooth transitions without wobble (default: 1) - Too high (2+): Sluggish response, may feel unresponsive

    Increase if motorcycle wobbles side-to-side. Decrease if lean transitions feel too dampened.

    gainIntegral

    PID controller integral gain for lean error correction.

    Declaration
    [Tooltip("Lean PID controller integral gain.")]
    public float gainIntegral
    Field Value
    Type Description
    float
    Remarks

    Accumulates lean angle error over time to eliminate steady-state offset. Ensures the motorcycle reaches and maintains the target lean angle.

    Tuning guide: - Too low (0-3): May not fully reach target lean, constant offset - Optimal (3-8): Accurate lean targeting (default: 4) - Too high (8+): Aggressive corrections, potential instability

    Increase if motorcycle doesn't lean enough in corners. Decrease if corrections feel too aggressive.

    gainProportional

    PID controller proportional gain for immediate lean response.

    Declaration
    [Tooltip("Lean PID controller proportional gain.")]
    public float gainProportional
    Field Value
    Type Description
    float
    Remarks

    Primary gain controlling the immediate response to lean angle error. Determines how aggressively the motorcycle tries to achieve target lean.

    Tuning guide: - Too low (0-2): Slow lean response, may fall over in turns - Optimal (2-6): Responsive but stable (default: 5) - Too high (6+): Twitchy, overcorrects, unrealistic "magnetic" balance

    This is usually the first parameter to adjust when tuning. Start here if the motorcycle feels too stable or unstable.

    gripLimitedCamberThrust

    Grip-limit the lean cornering force. When true, the lateral force from lean is tan(lean)*load capped at the tire's peak mu, and the target lean is capped at atan(mu) - so cornering saturates and the bike runs wide / washes out on low grip, like a real bike. When false, the legacy arcade injection (sin(lean)*load, never grip-limited, "on rails") is used.

    Declaration
    [Tooltip("Cap lean cornering force at tire grip (tan(lean), clamped to mu). Off = legacy arcade on-rails feel.")]
    public bool gripLimitedCamberThrust
    Field Value
    Type Description
    bool

    handlebarsTransform

    Transform representing the upper forks and handlebars for visual steering animation.

    Declaration
    [Tooltip("Transform representing the upper forks and handlebars.")]
    public Transform handlebarsTransform
    Field Value
    Type Description
    Transform
    Remarks

    Automatically rotates to match the front wheel's steering angle. Provides visual feedback for player steering input.

    Setup: - Assign the handlebar/fork GameObject transform - Ensure proper pivot point at the steering axis - Initial rotation is stored and used as reference

    integralLimitFraction

    Integral windup cap as a fraction of maxLeanTorque. Lower removes rubber-band lag/overshoot on quick lean reversals (chicanes) without reducing proportional authority.

    Declaration
    [Tooltip("Integral windup cap as a fraction of maxLeanTorque.")]
    [Range(0.1, 1)]
    public float integralLimitFraction
    Field Value
    Type Description
    float

    leanAngleMaxDelta

    Maximum lean angle change rate (degrees/second) at different speeds.

    Declaration
    [Tooltip("Maximum angle delta in [deg] per [s] for given speed [m/s].")]
    public AnimationCurve leanAngleMaxDelta
    Field Value
    Type Description
    AnimationCurve
    Remarks

    Defines how quickly the motorcycle can change its lean angle based on current speed. X-axis: Speed (m/s), Y-axis: Max lean rate (deg/s).

    Default curve: - 0 m/s: 220 deg/s (quick transitions at low speed) - 90 m/s: 100 deg/s (slower transitions at high speed)

    Physics rationale: At low speeds, riders can quickly shift weight and balance. At high speeds, gyroscopic forces resist rapid lean changes.

    Adjustment guide: - Increase Y values for more arcade-like quick lean transitions - Decrease Y values for more realistic, heavier feel - Adjust curve shape to fine-tune speed-dependent behavior

    leanAngleSlipCoefficient

    Additional lean angle applied based on rear wheel lateral slip.

    Declaration
    [Tooltip("Lean angle addition given the lateral tire slip.\r\nAllows the motorcycle to lean and slide sideways when drifting,\r\ninstead of highsiding.")]
    public float leanAngleSlipCoefficient
    Field Value
    Type Description
    float
    Remarks

    Prevents highsiding by leaning the motorcycle into slides. Negative values lean into the slide direction (realistic). Positive values lean away from slide (unrealistic but may help stability).

    Recommended values: - -40 to -20: Strong slip compensation, very forgiving - -30: Balanced compensation (default) - -15 to 0: Minimal compensation, more realistic but harder

    How it works: When the rear wheel slides laterally, this adds corrective lean to maintain balance, simulating natural rider reactions and preventing the violent highside crashes common in motorcycle physics.

    leanPIDCoefficient

    Global multiplier for all PID gain values.

    Declaration
    [Tooltip("Global multiplier for all PID gains. Higher = more stable, lower = more realistic.")]
    public float leanPIDCoefficient
    Field Value
    Type Description
    float
    Remarks

    Scales all three PID gains simultaneously while preserving their ratios. Useful for quick overall stability adjustments without changing individual gains.

    Recommended values: - 10-30: Light assistance, allows falling over (realistic/hard) - 40-60: Balanced assistance (default: 50) - 70-100: Strong assistance, very stable (arcade)

    Use this as a "difficulty" slider: Lower values = more realistic but harder Higher values = more forgiving and arcade-like

    maxLeanAngle

    Maximum achievable lean angle (degrees) at different speeds.

    Declaration
    [Tooltip("Maximum lean angle [deg] for given speed [m/s]. Runtime-capped by atan(mu) when grip-limited.")]
    public AnimationCurve maxLeanAngle
    Field Value
    Type Description
    AnimationCurve
    Remarks

    Defines the lean angle limit based on current speed. X-axis: Speed (m/s), Y-axis: Max lean angle (degrees).

    Typical real-world values: - Street bikes: 35-45 degrees - Sport bikes: 45-55 degrees - Racing bikes: 55-65 degrees

    Default curve (33 degrees) provides a conservative street bike feel. Increase for more aggressive cornering capability. Can vary by speed to simulate aerodynamic or stability limits.

    Note: Actual achievable lean also depends on tire grip, surface conditions, and the PID controller's ability to maintain balance.

    maxLeanTorque

    Maximum corrective torque (Nm) the balance system can apply.

    Declaration
    [Tooltip("Maximum torque the lean controller can apply to the Rigidbody.\r\nToo small value will result in lack of lean control on the vehicle\r\nin extreme cases, but can be more realistic as the motorcycle will be able to\r\nfall over, highside, etc.")]
    public float maxLeanTorque
    Field Value
    Type Description
    float
    Remarks

    Limits the PID controller's authority to prevent unrealistic "magnetic" balance. Acts as a saturation limit for the control system.

    Recommended values based on vehicle mass: - Light bikes (150kg): 3000-5000 Nm - Medium bikes (250kg): 5000-8000 Nm (default: 7000) - Heavy bikes (400kg+): 8000-12000 Nm

    Tuning guide: - Too low: Motorcycle can't recover from extreme lean, falls easily - Optimal: Recovers from most situations but can still fall - Too high: Unrealistic recovery from any angle, never falls

    For realistic gameplay, set this just high enough to handle normal riding but allow crashes in extreme situations.

    selfRightStrength

    Strength of the optional self-righting torque applied when the bike has fallen past the balance threshold. 0 (default) leaves a downed bike terminal (realistic); raise for an arcade pick-up.

    Declaration
    [Tooltip("Self-right torque strength once fallen over. 0 = stays down (realistic), higher = arcade recovery.")]
    [Range(0, 1)]
    public float selfRightStrength
    Field Value
    Type Description
    float

    slipCompensationDeadZone

    Minimum lateral slip value before slip compensation is applied.

    Declaration
    [Tooltip("Minimum slip value before it affects lean. Filters numerical noise.")]
    [Range(0, 0.2)]
    public float slipCompensationDeadZone
    Field Value
    Type Description
    float

    slipCompensationSteeringThreshold

    Minimum steering input required before slip compensation affects lean target.

    Declaration
    [Tooltip("Minimum steering input before slip compensation affects lean. Prevents straight-line drift.")]
    [Range(0, 0.3)]
    public float slipCompensationSteeringThreshold
    Field Value
    Type Description
    float

    swingarmTransform

    Transform representing the rear swingarm for visual suspension animation.

    Declaration
    [Tooltip("Transform representing the rear swingarm.")]
    public Transform swingarmTransform
    Field Value
    Type Description
    Transform
    Remarks

    Automatically rotates to track the rear wheel position, simulating swingarm movement as the suspension compresses/extends.

    Setup: - Assign the swingarm GameObject transform - Ensure pivot point is at the swingarm's rotation axis - Swingarm will use LookAt to track the wheel position

    useHitNormalAsUp

    Use ground normal instead of world up for lean angle calculation.

    Declaration
    [Tooltip("Should the wheel hit normal be used as the up reference when calculating the lean angle?\r\nNormally world up is used, but this can be problematic with loops, leaning track, etc.")]
    public bool useHitNormalAsUp
    Field Value
    Type Description
    bool
    Remarks

    When enabled, lean angle is calculated relative to the ground surface rather than world up vector. Essential for non-flat terrain.

    Enable for: - Banked/curved tracks - Loop-the-loops and wall rides - Off-road terrain with slopes - Any non-flat racing surface

    Disable for: - Perfectly flat tracks only - When consistent world-relative lean is needed

    When enabled, the motorcycle will maintain proper lean angle relative to the riding surface, allowing for realistic banking on curved tracks and hillsides.

    Properties

    FrontWheelGrounded

    Indicates whether the front wheel is in contact with the ground.

    Declaration
    public bool FrontWheelGrounded { get; }
    Property Value
    Type Description
    bool
    Remarks

    Useful for detecting wheelies, jumps, and front wheel traction loss. Can be used to adjust physics behavior or trigger animations/effects.

    IsStoppie

    True when only the front wheel is grounded (rear wheel lifted).

    Declaration
    public bool IsStoppie { get; }
    Property Value
    Type Description
    bool

    IsWheelie

    True when only the rear wheel is grounded (front wheel lifted).

    Declaration
    public bool IsWheelie { get; }
    Property Value
    Type Description
    bool

    RearWheelGrounded

    Indicates whether the rear wheel is in contact with the ground.

    Declaration
    public bool RearWheelGrounded { get; }
    Property Value
    Type Description
    bool
    Remarks

    Primary drive wheel ground contact. Loss of rear wheel contact typically means loss of acceleration and potential loss of control.

    isGrounded

    True when both wheels are in contact with the ground.

    Declaration
    public bool isGrounded { get; }
    Property Value
    Type Description
    bool

    Methods

    VC_Disable(bool)

    Disables the motorcycle module and applies high angular damping to prevent tipping.

    Declaration
    public override bool VC_Disable(bool calledByParent)
    Parameters
    Type Name Description
    bool calledByParent

    Whether this was called by the parent component or LOD system.

    Returns
    Type Description
    bool

    True if successfully disabled, false otherwise.

    Overrides
    VehicleComponent.VC_Disable(bool)
    Remarks

    When disabled (e.g., when parked), applies high angular damping to keep the motorcycle upright since the PID controller is no longer running. Also resets the lean angle to zero.

    VC_Enable(bool)

    Enables the motorcycle module and removes angular damping for proper lean physics.

    Declaration
    public override bool VC_Enable(bool calledByParent)
    Parameters
    Type Name Description
    bool calledByParent

    Whether this was called by the parent component or LOD system.

    Returns
    Type Description
    bool

    True if successfully enabled, false otherwise.

    Overrides
    VehicleComponent.VC_Enable(bool)
    Remarks

    Sets angular damping to zero to allow free rotation for lean dynamics. When disabled, high damping is applied to keep the motorcycle upright.

    VC_FixedUpdate(float)

    Physics update that applies lean control torque and updates visual components.

    Declaration
    public override void VC_FixedUpdate(float DeltaTime)
    Parameters
    Type Name Description
    float DeltaTime

    Fixed timestep delta time in seconds.

    Overrides
    VehicleComponent.VC_FixedUpdate(float)
    Remarks

    Main physics loop that: - Calculates current lean angle relative to ground or world up - Determines target lean based on steering input and slip compensation - Applies PID-controlled torque to maintain balance - Updates visual elements (handlebars and swingarm)

    The lean torque is calculated using a PID controller that compares current lean angle to the target angle. Slip compensation prevents highsiding by adding corrective lean when the rear wheel slides laterally.

    VC_Initialize()

    Initializes the motorcycle module by setting up wheel references and PID controller.

    Declaration
    protected override void VC_Initialize()
    Overrides
    VehicleComponent.VC_Initialize()
    Remarks

    Validates that exactly two wheels are present and caches references to front and rear wheels. Initializes the lean PID controller with configured gains and stores initial handlebar rotation.

    VC_Update(float)

    Frame-rate dependent update called every frame. Override for visual updates and input handling.

    Declaration
    public override void VC_Update(float DeltaTime)
    Parameters
    Type Name Description
    float DeltaTime

    Time elapsed since last Update in seconds

    Overrides
    VehicleComponent.VC_Update(float)
    Remarks

    Only called when the component is active (initialized and enabled). Use for visual effects, UI updates, and other frame-dependent operations. Avoid physics calculations here - use VC_FixedUpdate instead.

    VC_Validate(VehicleController)

    Validates the component configuration and reports any setup issues. Override to implement component-specific validation rules.

    Declaration
    public override void VC_Validate(VehicleController vc)
    Parameters
    Type Name Description
    VehicleController vc

    Parent VehicleController to validate against

    Overrides
    VehicleComponent.VC_Validate(VehicleController)
    Remarks

    Called in Editor when validation is triggered manually or automatically. Should use Debug.LogWarning/Error to report configuration problems. Check for null references, invalid values, missing dependencies, etc.

    See Also

    ModuleManager
    VehicleController
    WheelComponent
    Steering
    In this article
    Back to top Copyright © NWH - Vehicle Physics, Aerodynamics, Dynamic Water Physics