NWH Vehicle Physics 2
Search Results for

    Show / Hide Table of Contents

    FFB Input Provider (Steering Wheel Support)

    FFBInputProvider adds steering wheel support with force feedback (FFB) to NWH Vehicle Physics 2 using the DirectInput API. It works with any DirectInput-compatible device including Logitech, Thrustmaster, Fanatec, Moza, Simagic, Simucube, and other manufacturers.

    Warning: Windows only - DirectInput does not exist on other platforms. The target vehicle must have at least one steered wheel with a WheelController; a single steered wheel is supported for motorcycles.

    The force sent to the wheel comes from the tire model, not preset effects. Self-aligning torque comes from the tires' aligning moment in the physics step, so the wheel lightens as the front tires approach the grip limit and gains weight again as they recover.

    Compatible Devices

    All DirectInput-compatible devices work, including:

    Device Status
    Simucube 2 Pro/Ultimate Verified
    Fanatec DD1/DD2/CSL DD Verified
    Moza R9 Verified
    Simagic Alpha Verified
    Logitech G29/G920/G923/PRO Verified
    Thrustmaster TX/T300 Verified

    Setup

    With NWH Vehicle Physics 2 installed, the demo needs two imports: its Direct Input FFB Sample and the Unity-DirectInput Git package below. Unity-DirectInput supplies the DirectInput and force feedback libraries. The NVP2 sample contains the scene, vehicle, driving area, camera, and FFB components. No other samples are required.

    Use Windows with a Windows 64-bit profile active in File > Build Profiles. Input System and URP are installed with Vehicle Physics 2; enable Input System Package (New) or Both under Player > Active Input Handling if needed.

    1. Install Unity-DirectInput Package

    Add the Unity-DirectInput package via Unity Package Manager:

    1. Open Window > Package Manager
    2. Click the + button and select Add package from git URL
    3. Enter: https://github.com/arescec/Unity-DirectInput-NVP2.git#v1.2.1
    4. Click Install
    5. Restart Unity after installation

    Use the full URL, including #v1.2.1, to install the compatible library release. Git must be installed and available on your PATH for Package Manager to install Git packages.

    2. Import the Direct Input FFB Sample

    In Window > Package Manager, select NWH Vehicle Physics 2, expand Samples, and import Direct Input FFB Sample. You can also import this sample before installing Unity-DirectInput; its scripts activate automatically once the dependency is installed. No scripting defines or assembly reference edits are needed.

    Upgrade note: do not import the old DirectInput package sample named NWH Vehicle Physics 2 v13 FFB Sample Demo. It contains the retired v13 provider. Unity-DirectInput 1.2.1 contains only the libraries; import the current sample from NVP2.

    3. Open the Demo Scene

    Open Scenes/NVP2 FFB Demo.unity in the imported sample under Assets/Samples/NWH Vehicle Physics 2/<version>/Direct Input FFB Sample/.

    The scene already contains the vehicle, DirectInputManager, and FFBInputProvider. Configure your controls and wheelbase settings below, then enter Play mode. The manager selects the first connected FFB-capable device. Use its FFB Device Search Term to prefer a particular wheel when several are connected.

    4. Configure Input Mappings

    Steering and the remaining controls use two different lookup paths:

    • steeringAxis is the physical DirectInput axis name read directly from the selected FFB device. Its sample default is X; it is not a DIInputManager.inputMappings key.
    • throttleAxis, brakeAxis, clutchAxis, handbrakeAxis, and all button fields are logical mapping names. Each non-empty field must match a mappingName on DIInputManager; set that mapping's Input Name to the physical axis or button reported by your device.

    The sample provider uses the logical names throttle, brake, and clutch. Its analog handbrake field is empty by default; set it to handbrake if you configure that sample mapping. The sample manager contains several common pedal, sequential-shifter, and H-pattern mappings, but their physical Input Name values are intentionally blank because those names vary by device.

    The provider also exposes optional logical names such as neutral, gears 8 and 9, alternate shift buttons, and handbrakeButton. The sample manager does not contain every optional mapping. Add a mapping with the same name before using one of those fields. A misspelled or unconfigured logical name produces no input.

    5. Set Wheelbase Torque and Check Polarity

    Set wheelbaseTorque to your device's actual peak torque before anything else - every force in the system is scaled against it.

    Then check the direction of the force. Output polarity is not the same on every device: DirectInput does not define which sign means "push left", so roughly half of all wheels need the output inverted. Drive slowly and turn:

    • Correct: the wheel resists the turn and tries to return to centre.
    • Wrong: the wheel pulls itself further into the turn and runs to full lock.

    If it is wrong, enable invertFFBOutput. Do not try to correct it with negative coefficients elsewhere - that inverts the detail effects along with the main force.

    invertFFBOutput, softLockStrength, softLockRampDeg, and collisionFullScaleDeltaV are available in the regular Force Feedback Settings inspector section.

    Using FFB in Your Own Scene

    Add the sample's DirectInputManager and FFBInputProvider prefabs, then assign your vehicle to the provider's Vehicle Controller field. Optionally add FFBVehicleSettings to that vehicle for per-vehicle tuning.

    The prefabs are separate: FFBInputProvider does not contain a DIInputManager. Keep exactly one manager in the scene before entering Play mode. Keep the scene input provider used by your cameras, vehicle switching, or UI.

    FFBInputProvider Settings

    The sections below match the inspector layout.

    Core Settings

    Setting Description
    vehicleController Vehicle to read forces from. Follows the active vehicle if a VehicleChanger is present.
    useDirectInput Sets Steering.useRawInput, bypassing the Steering component's angle-curve, steering-rate, and speed-sensitivity processing. VehicleInputHandler smoothing is separate; for direct wheel response set its Steering Smoothing Time and Steering Return Time to 0.
    hShifterUse34asDR Uses H-pattern positions 3 and 4 as Drive and Reverse, for an automatic gearbox driven with a shifter.

    Hardware Configuration

    Setting Description
    wheelbaseTorque Peak torque of your wheel in Nm. G29/G923 = 2-3, T300 = 4-5, CSL DD = 5-8, Moza R9 = 9, DD1/DD2 = 15-20, Simucube 2 Pro = 25. Set this correctly first - it is the reference every other force is scaled against.
    deviceRotationRange Physical rotation range the wheel is configured for in its driver, in degrees (typically 900). Must match the driver setting or the steering angle will not line up.
    steeringSensitivity Multiplier on steering input. Leave at 1 for a 1:1 wheel.

    Steering Geometry

    These two settings control how much steering weight comes from vertical load rather than lateral force. This load-based weight remains during a slide and decreases over a crest, so the driver feels changes in road load as well as tire grip.

    Setting Description
    casterAngle Caster in degrees. 3-7 for road cars, 5-8 for rally. Overridden per vehicle by FFBVehicleSettings.casterAngle when that is above 0.
    kingpinOffset Lateral distance from the kingpin axis to the contact patch, in metres. Drives parking effort and the lightening felt over a crest.

    Force Feedback Settings

    Setting Description
    overallEffectStrength Master multiplier. 0 disables force feedback.
    forceFeedbackEffect Curve scaling FFB strength against steering angle.
    springEffect Curve scaling the DirectInput spring effect against steering angle.
    springEffectStrength DirectInput spring (centring) effect. 0 by default - centring already comes from the tire model.
    lowSpeedFriction Steering resistance while stationary or nearly so.
    friction Steering resistance at speed.
    centeringForceStrength Legacy suspension-based centring.
    centeringForceOffset Offsets the centre by the drift angle, so the wheel centres on the direction of travel rather than straight ahead.
    collisionEffectMultiplier Strength of the impact jolt.

    High-Rate Output and Mixing

    Force is sent to the device from a dedicated thread rather than once per rendered frame, so kerb and grip-limit detail is not tied to your framerate.

    Setting Description
    ffbThreadHz Output rate of the FFB thread. The default 333 Hz covers the 40-150 Hz band where kerb, rut and grip-limit detail live. Lower it only if you are chasing CPU.
    textureBudget Ceiling on the combined road-texture effects as a fraction of full force, before mixing with the self-aligning torque. Keeps detail from drowning out the main force.
    softClipKnee Force is linear up to this fraction of full scale, then compresses smoothly instead of clipping flat. 1 = hard clip.
    maxSlewNmPerSec Limit on how fast output torque may change, in Nm/s. Bounds impact spikes a real steering rack could not produce. 0 = unlimited.

    Damping and Centering

    Setting Description
    damperStrength Velocity damper strength. Stabilises the wheel without attenuating the tire signal.
    damperFadeSpeed Vehicle speed (m/s) at which the damper drops to its high-speed floor.
    damperHighSpeedFloor Damper multiplier at and above the fade speed. This is the steering "drag" felt at speed - too low and a direct-drive wheel feels like it is freewheeling, too high and road detail smears.
    frictionCoeffAmount Small constant DirectInput friction so the wheel never feels loose. Fades as the tires start to slide.
    suspensionCenteringStrength Legacy suspension-difference centring offset. 0 by default; useful only on low-torque belt or gear wheels.

    Texture Effects

    Setting Description
    roadTextureStrength Strength of road texture. Derived by high-pass filtering the real rack force, so it is automatically correct for surface and speed. 0 = off.

    Note: earlier versions had separate kerb, scrub, engine-resonance and ABS oscillators. Those were fixed-frequency tones advanced once per frame, which aliases - a 55 Hz kerb tone folds down to about 5 Hz at 60 fps, and its pitch changes with framerate. They are replaced by this single term.

    Suspension Feedback

    Setting Description
    suspensionBumpStrength Kerb, pothole and road-surface feel through the steering.
    suspensionBumpThreshold Minimum suspension velocity (m/s) before bump feedback triggers. Lower is more sensitive.

    Input Inversion, Axes and Deadzones

    flipSteeringInput, flipThrottleInput, flipBrakeInput, flipClutchInput and flipHandbrakeInput invert a pedal or axis that reads backwards. The pedal flips default to on, which suits most wheels - a pedal that reads full when released usually needs its flip turned off, not on.

    steeringAxis0to1 tells the provider whether the steering axis reports 0-1 (most devices) or already reports -1 to 1.

    Deadzones (throttleDeadzone, brakeDeadzone, clutchDeadzone, handbrakeDeadzone, steeringDeadzone) trim noise around the resting position of worn pedals. Steering deadzone defaults to 0 and should normally stay there.

    steeringAxis is the selected FFB device's physical DirectInput axis name. The pedal, handbrake, and shifter fields are logical DIInputManager mapping names, as described in setup step 4.

    Output Direction, Soft Lock, and Collision Scaling

    Setting Description
    invertFFBOutput Flips the sign of the force sent to the device. See step 5 of Setup.
    softLockStrength Strength of the end stop felt past full steering lock, as a fraction of full device torque. 0 disables it.
    softLockRampDeg Degrees of wheel travel past lock over which the end stop ramps up to full strength.
    collisionFullScaleDeltaV Impact speed change (m/s) that produces a full-scale collision jolt.

    Per-Vehicle Tuning

    Add FFBVehicleSettings to your VehicleController GameObject to scale FFB per vehicle. A truck and a formula car want different steering weight from the same physical wheel.

    Setting Description
    overallCoeff Overall FFB strength for this vehicle.
    satCoefficient Self-aligning torque multiplier.
    mechanicalTrailCoeff Multiplier on the caster/kingpin load term. 0 = tire trail only (very light), 0.2 = baseline, above 1 = exaggerated weight.
    centeringCoeff Centring force multiplier.
    casterAngle Caster for this vehicle. 0 = use the provider's global value.
    kingpinOffset Kingpin offset for this vehicle, in metres. Negative = use global.
    wheelRotationRange Steering wheel rotation range for this vehicle, in degrees.
    staticFrontLoadOverride Measured static front axle load in Newtons, used to normalise how load modulates the rack force. 0 = estimate as half the vehicle weight.
    frictionCoeff At-speed friction multiplier.
    lowSpeedFrictionCoeff Stationary friction multiplier.
    longitudinalCoeff How much braking and acceleration are felt through the steering.
    scrubRadius Scrub radius in metres. Typical 0.01-0.03 for road cars.
    suspensionBumpStrength Bump feedback for this vehicle. Negative = use global.
    suspensionBumpThreshold Bump sensitivity for this vehicle. Negative = use global.

    Gotcha: fields whose "inherit" value is negative (kingpinOffset, suspensionBumpStrength, suspensionBumpThreshold) treat 0 as a real value meaning off. Leave them negative unless you actually want that effect disabled on this vehicle. When upgrading from v14 Beta 2, serialized zero values for the two suspension fields are migrated automatically to the negative inherit value.

    Gotcha: wheelRotationRange here also sets the steering ratio used to convert rack torque to torque at the rim. It is not the same field as Steering.steeringWheelTurnRatio, which only rotates the in-game steering wheel mesh and does nothing if no mesh is assigned.

    Tuning by Wheel Type

    Direct drive (CSL DD, R9, Alpha, Simucube). Defaults are aimed here. Set wheelbaseTorque correctly, leave springEffectStrength and suspensionCenteringStrength at 0, and tune feel with damperHighSpeedFloor - it is the single knob that decides whether the wheel feels planted or loose at speed.

    Belt and gear wheels (T300, G29, G923). These have mechanical friction and less headroom. Raising springEffectStrength and suspensionCenteringStrength above 0 helps the wheel find centre, and lowering textureBudget keeps detail from eating the limited torque available for the main force.

    Clipping. If _compressionPct sits high in the debug readout, the soft clip is working constantly and detail is being squashed. Lower overallEffectStrength or the per-vehicle overallCoeff rather than raising wheelbaseTorque above the device's real figure.

    Diagnostics

    In play mode the inspector shows a Debug Values section:

    Readout Meaning
    _signedSatNm Signed steering-column torque in Nm. Use this to confirm polarity: turning right should give a torque pushing back toward centre.
    _primaryForcePct Share of output coming from the self-aligning torque.
    _effectsForcePct Share coming from texture and secondary effects.
    _totalForcePct Total output as a percentage of full device torque.
    _compressionPct How hard the soft clip is compressing. Persistently high means you are asking for more torque than the device has.

    Troubleshooting

    Wheel Pulls Into the Turn Instead of Centering

    Output polarity is inverted for your device. Enable Invert FFB Output in the regular FFBInputProvider inspector.

    Device Not Detected

    • Ensure Unity-DirectInput package is installed
    • Restart Unity after installation
    • Check that your device appears in Windows Game Controllers
    • Try disconnecting and reconnecting the device
    • Check there is only one DIInputManager in the scene

    Slow Enumeration

    DirectInput device enumeration can occasionally take up to 60 seconds due to a Windows bug. USB Audio DACs and certain keyboards (e.g. Corsair) can cause this. Try disconnecting non-essential USB devices.

    Force Feedback Not Working

    • Verify overallEffectStrength is greater than 0
    • Check wheelbaseTorque matches your wheel's actual torque output
    • Ensure the vehicle has at least one steered wheel with a WheelController. Motorcycles may use one steered wheel.
    • Check DIInputManager shows your device as FFB-capable

    Forces Cut Out After a Pause or Script Recompile

    Output fades to zero if the physics step stops publishing for 250 ms, including during pauses, domain reloads, and main-thread stalls. It recovers automatically when the game resumes.

    Wheel Feels Numb or Over-Damped

    Lower damperHighSpeedFloor first. If the wheel then oscillates around centre, raise it back slightly rather than adding spring or centring force.

    Extending the Provider

    If you are modifying FFBInputProvider, the output loop runs on its own thread. No UnityEngine API may be called from it - not Time, not AnimationCurve.Evaluate, not any UnityEngine.Object access, not Debug.Log. Mathf is safe because it is pure static maths. Anything else must be sampled during FixedUpdate and passed across in the snapshot struct the thread reads. Breaking this rule hangs the editor rather than producing a warning.

    Requirements

    • Unity-DirectInput package 1.2.1, installed with the full Git URL in setup step 1
    • NWH Vehicle Physics 2 Direct Input FFB Sample
    • Windows 10/11 with a Windows 64-bit Build Profile active
    • DirectInput-compatible steering wheel with force feedback
    • Vehicle must have at least one steered wheel with a WheelController; a single steered wheel is supported
    In this article
    Back to top Copyright © NWH - Vehicle Physics, Aerodynamics, Dynamic Water Physics