Ship Input
AdvancedShipController.input is a ShipInputHandler. It polls the
ShipInputProvider components registered in the scene and writes the result to a
ShipInputStates value.
The input classes are in the NWH.DWP2.ShipController namespace. The shared
InputProvider registry is in NWH.Common.Input.
How ship input is combined
- Numeric values from all
ShipInputProviderinstances are added. - Boolean values are combined with a logical OR.
ShipInputHandler.statescontains the currentShipInputStates.- Properties such as
ShipInputHandler.SteeringandShipInputHandler.Throttleclamp and update the corresponding state fields. SceneInputProviderBaseproviders from NWH Common handle scene features such as camera and vehicle changing. They are not required for basic ship control.
Important
Ship input providers are scene-global contributors. Add one provider for the input source you want to use. Adding duplicate providers makes both contribute to every locally controlled ship.
Input System provider
The package manifest requires Unity 6000.0.80f1 or newer and declares Input
System 1.11.2. The shipped samples use InputSystemShipInputProvider.
- In Edit > Project Settings > Player, set Active Input Handling to Input System Package (New) or Both.
- Add one
InputSystemShipInputProvidercomponent to a scene object. - If the scene also uses the NWH Common camera or vehicle changers, add one
InputSystemSceneInputProvider. - Use runtime rebinding or a project-owned action asset/provider for project-specific ship controls instead of editing a registry package cache.
InputSystemShipInputProvider creates and enables its generated
ShipInputActions wrapper in Awake; there is no Input Action Asset reference
to assign in the inspector. The shipped asset and wrapper are frozen for deterministic package
imports. Package maintainers changing the action asset in a writable embedded package must
temporarily enable Generate C# Class, save and regenerate the wrapper, review it, and disable
generation again before redistribution.
Shipped Input System bindings
| Action | Value | Keyboard | Gamepad |
|---|---|---|---|
Steering |
-1 port, +1 starboard | A / D | Left stick left / right |
Throttle |
-1 reverse, +1 forward | S / W | Left trigger / right trigger |
Throttle2 |
-1 / +1 | 5 / 6 | Unbound |
Throttle3 |
-1 / +1 | 7 / 8 | Unbound |
Throttle4 |
-1 / +1 | 9 / 0 | Unbound |
BowThruster |
-1 / +1 | Q / E | Unbound |
SternThruster |
-1 / +1 | Z / X | Unbound |
SubmarineDepth |
-1 surface, +1 dive | K / I | Unbound |
EngineStartStop |
Button | R | Unbound |
Anchor |
Button | T | Unbound |
RotateSail |
-1 / +1 | 1 / 3 | Left shoulder / right shoulder |
Legacy Input Manager provider
The legacy Input Manager remains supported by
InputManagerShipInputProvider. Input System 1.11.2 is still a declared package
dependency even when the legacy provider is selected.
- Set Active Input Handling to Input Manager (Old) or Both.
- Add one
InputManagerShipInputProviderto a scene object. - Add the required axes and buttons in Edit > Project Settings > Input
Manager. A serialized starting set is shipped as
Runtime/ShipController/Input/InputProviders/InputManagerProvider/InputBindings.txt. - Add an
InputManagerSceneInputProvideronly if NWH Common scene controls are also needed.
The provider reads these exact names:
- Axes:
Steering,Throttle,Throttle2,Throttle3,Throttle4,BowThruster,SternThruster,SubmarineDepth, andRotateSail. - Buttons:
EngineStartStopandAnchor. - The provider also exposes
DragObjectPosition()andDragObjectModifier(), which read theMouse XandMouse Yaxes and aDragObjectModifierbutton. Nothing in the package calls them; they only matter to project code that does.Mouse XandMouse Yare part of Unity's default Input Manager set, andDragObjectModifierfalls back to Left Ctrl.
Bindings for controls a ship does not use may be omitted. A missing axis returns
zero and produces a warning. Missing EngineStartStop and Anchor buttons warn
and fall back to R and T respectively. The warnings share a budget of 100 per play session, so a
missing binding polled every frame stops reporting once that is used up.
Mobile provider
Add one MobileShipInputProvider and assign only the Unity UI sliders and
MobileInputButton fields that the ship needs. Unassigned fields return neutral
input. A MobileSceneInputProvider from NWH Common is optional and is used only
for scene controls.
For submarine controls, the depth slider must allow the complete -1 to +1 range so both surfacing and diving are reachable.
Reading combined input
InputProvider.CombinedInput<T>() requires the provider type as its generic
argument:
using NWH.Common.Input;
using NWH.DWP2.ShipController;
public static class ShipInputReader
{
public static float ReadCombinedThrottle()
{
return InputProvider.CombinedInput<ShipInputProvider>(
provider => provider.Throttle());
}
}
When a reference to a particular provider component is already available, call
that component directly, for example provider.Throttle().
Setting input from a script
Disable automatic polling with autoSetInput, then use the handler properties
or the matching ShipInputStates fields:
using NWH.DWP2.ShipController;
using UnityEngine;
public sealed class ScriptedShipInput : MonoBehaviour
{
[SerializeField] private AdvancedShipController ship;
private void Awake()
{
ship.input.autoSetInput = false;
}
private void Update()
{
ship.input.Steering = Mathf.Sin(Time.time);
ship.input.Throttle = 0.5f;
// Direct state access is also valid.
ship.input.states.steering = ship.input.Steering;
}
}
The current names are ShipInputHandler, ShipInputStates,
autoSetInput, Steering, and states.steering.
Creating a custom provider
Derive from ShipInputProvider and override only the controls supplied by the
new input source. The base implementations of the other controls return neutral
values.
using NWH.DWP2.ShipController;
using UnityEngine;
public sealed class ExampleShipInputProvider : ShipInputProvider
{
[Range(-1f, 1f)] public float steering;
[Range(-1f, 1f)] public float throttle;
public override float Steering()
{
return steering;
}
public override float Throttle()
{
return throttle;
}
}
Save the example as ExampleShipInputProvider.cs and add it once in the scene.
Keep another ship provider registered only when its values are intentionally
combined. Disabling a provider does not remove it from
InputProvider.Instances; remove or destroy it so OnDestroy() unregisters it.