Input

The input system retrieves control inputs from active InputProvider(s) and passes them to the vehicle through VehicleInputHandler. The system supports multiple input sources including keyboard/mouse, gamepad, mobile touch, and custom implementations.
Note: For detailed information about the shared Input System architecture and scene-level input, see NWH Common - Input System.
Input Architecture
InputProvider(s) → VehicleInputHandler → VehicleController
- InputProvider: Reads raw input from hardware (keyboard, gamepad, touch, etc.)
- VehicleInputHandler: Processes and distributes input to vehicle systems
- VehicleInputStates: Holds current input values (throttle, steering, etc.)
Input Providers
NVP2 includes three vehicle-specific input providers. Add the appropriate one to your vehicle based on your target platform.
InputSystemVehicleInputProvider
For projects using Unity's Input System package (com.unity.inputsystem).
Features:
- Action-based input with rebinding support
- Automatic device switching (keyboard ↔ gamepad)
- H-pattern shifter support (numeric keys 0-8, minus for reverse)
- Optional mouse steering
Setup:
- Install the Input System package via Package Manager
- Add
InputSystemVehicleInputProvidercomponent to the vehicle - (Optional) Modify bindings by double-clicking the
VehicleInputActionsasset
Default Bindings: | Action | Keyboard | Gamepad | |--------|----------|---------| | Throttle | W | Right Trigger | | Brake | S | Left Trigger | | Steering | A/D | Left Stick | | Handbrake | Space | A Button | | Shift Up | E | Right Bumper | | Shift Down | Q | Left Bumper | | Clutch | Left Ctrl | - |
InputManagerVehicleInputProvider
For projects using Unity's legacy Input Manager (Project Settings > Input).
Features:
- Works out of the box with default Unity input axes
- No additional packages required
- Mouse steering option
Setup:
- Add
InputManagerVehicleInputProvidercomponent to the vehicle - Ensure standard input axes are defined in Input Manager (Horizontal, Vertical, etc.)
MobileVehicleInputProvider
For mobile platforms (iOS, Android) with touch controls.
Features:
- On-screen steering wheel
- Touch buttons for throttle, brake, and all vehicle controls
- Accelerometer/gyroscope steering
- Multiple input method combinations
Steering Input Types:
SteeringWheel- Draggable on-screen wheel (requiresSteeringWheelcomponent)Accelerometer- Device tilt controls steeringButton- Left/right steering buttonsScreen- Touch screen areas
Throttle/Brake Input Types:
Button- Separate throttle and brake buttonsAccelerometer- Device tilt forward/backwardScreen- Touch screen areas
Setup:
- Add
MobileVehicleInputProviderto the vehicle - Add
MobileSceneInputProviderto the scene (for camera, pause, etc.) - Create UI Canvas with
MobileInputButtoncomponents - Assign buttons to the provider fields
- Configure
steeringInputTypeandverticalInputType
Example Configuration:
steeringInputType: SteeringWheel
verticalInputType: Button
tiltSensitivity: 1.5
Custom Input Provider
To create a custom input source (AI, replay system, network sync), extend VehicleInputProviderBase:
using NWH.VehiclePhysics2.Input;
public class AIVehicleInputProvider : VehicleInputProviderBase
{
public override float Throttle() => CalculateAIThrottle();
public override float Brakes() => CalculateAIBrakes();
public override float Steering() => CalculateAISteering();
// Override other methods as needed...
}
Available Methods to Override:
| Method | Return Type | Description |
|--------|-------------|-------------|
| Throttle() | float [0-1] | Throttle pedal position |
| Brakes() | float [0-1] | Brake pedal position |
| Steering() | float [-1,1] | Steering direction |
| Handbrake() | float [0-1] | Handbrake engagement |
| Clutch() | float [0-1] | Clutch pedal position |
| ShiftUp() | bool | Shift up button pressed |
| ShiftDown() | bool | Shift down button pressed |
| ShiftInto() | int | H-pattern gear (-1=R, 0=N, 1-8=gears) |
| EngineStartStop() | bool | Engine toggle pressed |
| Horn() | bool | Horn button held |
| Boost() | bool | Boost button held |
| CruiseControl() | bool | Cruise control toggle |
| LeftBlinker() | bool | Left turn signal toggle |
| RightBlinker() | bool | Right turn signal toggle |
| HazardLights() | bool | Hazard lights toggle |
| LowBeamLights() | bool | Headlights toggle |
| HighBeamLights() | bool | High beam toggle |
| ExtraLights() | bool | Fog/work lights toggle |
| TrailerAttachDetach() | bool | Trailer coupling toggle |
| FlipOver() | bool | Vehicle flip request |
VehicleInputHandler Properties
Input Swapping in Reverse
When swapInputInReverse is enabled (default: true), throttle and brake inputs swap when in reverse gear:
- Throttle input = move backward in reverse
- Brake input = slow down/stop when reversing
This makes reverse driving more intuitive by matching player expectations. The swapped values are available through InputSwappedThrottle and InputSwappedBrakes properties.
Disable for simulation games where direct throttle/brake control is preferred regardless of gear.
Steering Smoothing
The input handler includes built-in steering smoothing for keyboard input:
| Property | Type | Description |
|---|---|---|
steeringSmoothingTime |
float | Time to reach full steering from zero (0-0.5s). Recommended: 0.15-0.25s for keyboard |
steeringReturnTime |
float | Time for steering to return to center when released (0-0.5s) |
steeringDirectionChangeMultiplier |
float | Speed multiplier when changing direction (1-5x). Higher = snappier transitions |
Set both times to 0 to disable smoothing for direct input response.
Input Modification Callback
Use inputModifyCallback to modify input values after they're retrieved from providers but before vehicle systems process them:
vehicleController.input.inputModifyCallback.AddListener(() => {
// Example: Reduce steering at high speeds
float speed = vehicleController.Speed;
if (speed > 20f) {
vehicleController.input.Steering *= 0.7f;
}
});
Manual Input (AI/Replay)
Bypass input providers and set input directly for AI controllers or replay systems:
// Disable automatic input
vehicleController.input.autoSetInput = false;
// Option 1: Set throttle/brake separately
vehicleController.input.Throttle = 1f; // Full throttle
vehicleController.input.Brakes = 0f; // No braking
vehicleController.input.Steering = 0.5f; // Turn right
// Option 2: Use combined Vertical axis (positive = throttle, negative = brake)
vehicleController.input.Vertical = 1f; // Full throttle
vehicleController.input.Vertical = -1f; // Full brake
// Other inputs
vehicleController.input.Handbrake = 0f;
vehicleController.input.Clutch = 0f;