Input System
NWH Common provides a flexible, provider-based input system used by all NWH physics assets.
Overview
The input system uses the Provider Pattern to abstract input sources, allowing easy switching between:
- Unity Input Manager (legacy)
- Unity Input System (new)
- Custom input sources
- Mobile touch controls
Architecture
Core Components
InputProvider- Abstract base class for all input providers, manages a static list of active instancesSceneInputProviderBase- Abstract base class for scene-level input providers (camera, scene, character controls)
Provider Pattern
InputProvider (abstract)
│
└── SceneInputProviderBase (abstract)
├── InputManagerSceneInputProvider (Unity Input Manager)
├── InputSystemSceneInputProvider (Unity Input System)
├── MobileSceneInputProvider (Touch controls)
└── CustomInputProvider (your implementation)
How It Works
- A concrete input provider (e.g.,
InputManagerSceneInputProvider) is placed in the scene - Controllers query
InputProvider.Instancesor useInputProvider.CombinedInput()to get input - Input data is returned from provider methods that return specific input values
- Switching providers requires replacing the input provider component in the scene
Available Input Methods
Input providers expose the following methods for scene and camera control:
- ChangeCamera() - Returns true when the change camera button is pressed
- ChangeVehicle() - Returns true when the change vehicle button is pressed
- CameraRotation() - Returns camera rotation input as a Vector2
- CameraPanning() - Returns camera panning input as a Vector2
- CameraRotationModifier() - Returns true when camera rotation modifier is held
- CameraPanningModifier() - Returns true when camera panning modifier is held
- CameraZoom() - Returns camera zoom input (positive = zoom in, negative = zoom out)
- CharacterMovement() - Returns character movement input as a Vector2
- ToggleGUI() - Returns true when the toggle GUI button is pressed
For vehicle-specific inputs (steering, throttle, brake), consult the NWH Vehicle Physics 2 documentation.
Input Providers
Unity Input Manager Provider
Class: InputManagerSceneInputProvider
Uses Unity's legacy Input Manager (Project Settings > Input Manager).
Setup:
- Add
InputManagerSceneInputProvidercomponent to scene - Configure axis mappings in Input Manager (Project Settings > Input Manager)
- Configure button mappings for ChangeCamera and ChangeVehicle
- For vehicle-specific inputs, see NWH Vehicle Physics 2 documentation
Unity Input System Provider
Class: InputSystemSceneInputProvider
Uses Unity's new Input System package.
Setup:
- Install Input System package
- Add
InputSystemSceneInputProviderto scene - Assign Input Action Asset
- Enable Auto-Enable Input
Features:
- Full rebinding support
- Multiple control schemes
- Gamepad, keyboard, mouse support
- Better touch support
Mobile Provider
Class: MobileSceneInputProvider
Touch-based UI button provider for mobile devices.
Features:
- UI button support for ChangeCamera and ChangeVehicle actions
- Easy integration with mobile UI framework
- Lightweight implementation for mobile platforms
Creating Custom Input Providers
Extend SceneInputProviderBase to create custom scene-level input providers:
using NWH.Common.Input;
using UnityEngine;
public class MyCustomInputProvider : SceneInputProviderBase
{
public override bool ChangeCamera()
{
// Implement camera change detection
return Input.GetKeyDown(KeyCode.C);
}
public override bool ChangeVehicle()
{
// Implement vehicle change detection
return Input.GetKeyDown(KeyCode.V);
}
public override Vector2 CameraRotation()
{
// Implement camera rotation input
return new Vector2(
Input.GetAxis("Mouse X"),
Input.GetAxis("Mouse Y")
);
}
// Override other input methods as needed...
}
Then add your custom provider to the scene as a component.
Usage in Vehicle Controllers
Vehicle Physics 2
For use with NWH Vehicle Physics 2:
// VehicleController automatically queries available input providers
VehicleController vc = GetComponent<VehicleController>();
// Input is handled internally
Custom Controllers
using NWH.Common.Input;
using UnityEngine;
public class MySceneController : MonoBehaviour
{
private void Update()
{
if (InputProvider.Instances.Count == 0) return;
// Use CombinedInput to query all active input providers
Vector2 movement = InputProvider.CombinedInput<SceneInputProviderBase>(i => i.CharacterMovement());
Vector2 cameraLook = InputProvider.CombinedInput<SceneInputProviderBase>(i => i.CameraRotation());
bool changeVehicle = InputProvider.CombinedInput<SceneInputProviderBase>(i => i.ChangeVehicle() ? 1 : 0) > 0;
// Apply inputs to your controller...
if (changeVehicle)
{
// Handle vehicle change
}
}
}
Input Smoothing
Controllers can apply smoothing to input values:
public float smoothing = 0.1f; // Lower = smoother but more delayed
private Vector2 smoothedCameraRotation;
public void UpdateInput()
{
Vector2 rawInput = InputProvider.CombinedInput<SceneInputProviderBase>(i => i.CameraRotation());
smoothedCameraRotation = Vector2.Lerp(smoothedCameraRotation, rawInput, smoothing);
// Use smoothedCameraRotation for camera movement
}
Mobile Input Setup
For mobile games using MobileSceneInputProvider:
- Add MobileSceneInputProvider component to a GameObject in your scene
- Create UI Buttons:
- Add a
MobileInputButtoncomponent to each UI button you want to track - Assign these buttons to the provider's
changeCameraButtonandchangeVehicleButtonfields
- Add a
- Configure Button Behavior:
- Buttons trigger ChangeCamera() and ChangeVehicle() methods
- CharacterMovement and CameraRotation return zero by default (override if needed)
- Test on device (touch input doesn't work reliably in the Editor)
For vehicle-specific mobile controls (steering, throttle, brake), refer to the NWH Vehicle Physics 2 documentation.
Input Debugging
Enable debug mode in your input provider component in the Inspector to see live input values. You can also add logging to your custom input provider:
public override Vector2 CameraRotation()
{
Vector2 rotation = base.CameraRotation();
Debug.Log($"Camera Rotation: {rotation}");
return rotation;
}
Best Practices
- Multiple Providers - Multiple input providers can be active simultaneously; use
InputProvider.CombinedInput()to aggregate their inputs - Provider Selection - Choose provider based on platform:
- PC: InputSystemSceneInputProvider (recommended) or InputManagerSceneInputProvider (legacy)
- Mobile: MobileSceneInputProvider
- Custom: Extend SceneInputProviderBase with your own implementation
- Input Validation - Clamp and validate input before applying to physics
- Deadzone Handling - Apply deadzones for analog sticks
- Context-Aware Input - Disable input when UI is active
Common Issues
No input response:
- Check that a scene input provider (e.g., InputManagerSceneInputProvider) exists in the scene
- Verify the provider component is enabled
- Check input mappings in Input Manager (for InputManagerSceneInputProvider) or Input System asset (for InputSystemSceneInputProvider)
- Check that InputProvider.Instances is not empty
Jerky input:
- Apply smoothing in your controller using Mathf.Lerp()
- Enable interpolation on Rigidbody components
- Check Project Settings > Time > Fixed Timestep value
Controller not detected:
- For InputSystemSceneInputProvider: Check device is recognized in Window > Analysis > Input Debugger
- For InputManagerSceneInputProvider: Verify axis/button names match your Input Manager configuration
- Ensure the input provider is actively running in the scene
API Reference
For detailed API documentation, see the API reference in the navigation menu for: