Input System

RCC uses Unity's modern Input System package (not the legacy Input.GetAxis API). This document explains the full input pipeline: how keyboard and gamepad input reaches the vehicle, how to rebind keys, how mobile input differs, and how to add new inputs.

If you haven't installed the Input System package yet, do that first — see 02 — How to Install RCC.

The Input Pipeline

Physical Device (Keyboard / Gamepad / Touch / Wheel)
          ↓
RCC_InputActions.inputactions  (Input System binding asset)
          ↓
RCC_InputActions.cs  (auto-generated C# wrapper)
          ↓
RCC_InputManager (singleton, runs in Update)
          ↓
RCC_Inputs struct (throttle, brake, steer, etc.)
          ↓
RCC_CarControllerV4 reads inputs in FixedUpdate
          ↓
Vehicle moves

Every input — accelerating, braking, steering, shifting gears, toggling lights — flows through this pipeline. The key is the RCC_Inputs struct in the middle: it's a snapshot of what the player is doing right now, and every vehicle reads from it.

The Input Actions Asset

The binding configuration lives in:

Assets/RealisticCarControllerV4/Resources/RCC Assets/RCC_InputActions.inputactions

Open it by double-clicking. The Unity Input Actions editor opens, showing all the action maps and bindings.

Action Maps

The asset has these action maps:

Action Map Purpose
Vehicle Standard driving actions: throttle, brake, steer, etc.
Camera Camera control: change mode, orbit, look-back.
Optional Indicator toggles, headlights, slow motion, replay.

You can enable/disable maps independently — useful for, e.g., disabling the Vehicle map during a cutscene but keeping the Camera map active so the player can still look around.

Default Bindings

Each action has bindings for keyboard, gamepad, and (where applicable) mobile UI. The table in 04 — Demo Scenes lists all the default bindings.

Rebinding

To change a key:

  1. Open RCC_InputActions.inputactions.
  2. Expand the action you want to change (e.g., Vehicle / Throttle).
  3. Click the binding row to edit.
  4. Click Listen and press the new key (or gamepad button).
  5. Save.

Changes apply immediately the next time you enter Play mode.

Adding a New Binding

If you want to add a second key for an existing action (e.g., both W and Up Arrow for throttle):

  1. Open the action.
  2. Click the + next to the action name.
  3. Add the new binding.
  4. Save.

RCC_InputManager — The Singleton

The Input Manager is a runtime singleton (RCC_InputManager.Instance). It:

You don't usually touch this directly — it sets itself up automatically. But the public API lets you query current input state from any script:

RCC_Inputs currentInputs = RCC_InputManager.Instance.GetInputs();
float currentThrottle = currentInputs.throttleInput;

The RCC_Inputs Struct

The struct holds every numeric input value:

Field Range Meaning
throttleInput 0 to 1 Accelerator amount.
brakeInput 0 to 1 Brake amount.
steerInput -1 to 1 Steering direction. -1 = full left, 1 = full right.
clutchInput 0 to 1 Clutch disengagement. 0 = engaged, 1 = fully disengaged.
handbrakeInput 0 to 1 Handbrake amount.
boostInput 0 to 1 NOS / boost amount.
gearInput int Gear index for direct gear selection.
orbitX float Camera orbit horizontal.
orbitY float Camera orbit vertical.
scroll Vector2 Mouse wheel / camera zoom.

All values are clamped to their respective ranges by the input manager.

Reading Input in Your Own Scripts

If you want to read RCC's input from your own script (e.g., to play a custom sound when the player presses gas hard):

using UnityEngine;

public class GasMonitor : MonoBehaviour {
    void Update() {
        RCC_Inputs inputs = RCC_InputManager.Instance.GetInputs();
        if (inputs.throttleInput > 0.9f) {
            // Full throttle — do something.
        }
    }
}

This is the read-only path. To inject custom input into a vehicle (e.g., for AI or replay), see 17 — Overriding Inputs.

Listening for Input Events

For one-shot inputs (start engine, shift up, toggle headlights), the cleanest pattern is event subscription:

using UnityEngine;

public class EngineStartHandler : MonoBehaviour {
    void OnEnable() {
        RCC_Events.OnStartStopEngine += HandleEngineToggle;
    }

    void OnDisable() {
        RCC_Events.OnStartStopEngine -= HandleEngineToggle;
    }

    void HandleEngineToggle() {
        Debug.Log("Engine toggle pressed!");
        // Show key animation, play special sound, etc.
    }
}

The full event list is in 24 — Events System.

Gamepad Support

The default bindings work with any XInput-compatible controller (Xbox One, Xbox Series, third-party controllers). PlayStation controllers (DualShock 4, DualSense) also work — Unity Input System has built-in support.

If your gamepad isn't detected:

  1. Open the Input Debug window: Window → Analysis → Input Debugger.
  2. Look for your device in the Devices list.
  3. If it's not listed, the device drivers may be missing — check the manufacturer's site.

For older controllers (DirectInput / generic USB gamepads), the system may or may not detect them. As a workaround, use Steam Input or a tool like JoyToKey to map the controller to keyboard inputs that the Input System understands.

Steering Wheels

For Logitech G29, G27, G923, Thrustmaster, and other USB / FFB-capable wheels, see 25 — Steering Wheels for a detailed setup.

Mobile Input

On mobile platforms (iOS, Android), the default Input System path is not used. Instead, RCC reads from RCC_MobileButtons — a static class populated by the on-screen UI.

How to Switch to Mobile Mode

In RCC_Settings.asset, enable Mobile Controller Enabled. Pick the mobile controller type:

Then in the scene, use the RCC_Canvas (AIO).prefab UI canvas, which contains all the mobile UI widgets. The widgets are auto-hidden on desktop platforms.

Mobile Input Settings

In RCC_Settings:

See 18 — Mobile Setup for full mobile configuration.

Disabling Input

Three ways to make a vehicle stop accepting input:

1. Disable Per-Vehicle

carController.SetCanControl(false);

The vehicle ignores all input (throttle, steer, brake) but stays in the scene and physics still applies.

2. Disable Input System Maps

If you want to disable input globally (e.g., during a pause menu):

RCC_InputManager.Instance.DisableInputs();
// later:
RCC_InputManager.Instance.EnableInputs();

3. Use Override Inputs

For AI or replay, use the override path:

carController.overrideInputs = true;
// then feed inputs each frame via:
carController.OverrideInputs(myInputsStruct);

This bypasses the input manager entirely. See 17 — Overriding Inputs.

Common Input Issues

"Pressing W doesn't accelerate the car"

Most common cause: the Unity Input System backend isn't enabled. Open Edit → Project Settings → Player → Other Settings → Active Input Handling and set to Input System Package (New) or Both. Restart Unity.

"Gamepad controls work but keyboard doesn't (or vice versa)"

The Input Actions asset's bindings may have been modified. Open RCC_InputActions.inputactions and verify both keyboard and gamepad bindings exist for the actions you're testing.

"Steering is too fast / too slow"

In the Input Actions asset, the steer action has a Processors chain (typically Normalize Vector 2 for stick input). You can add a Scale processor with a multiplier to tune the input strength globally.

For a per-vehicle adjustment, modify steeringSensitivityFactor on the controller.

"Inputs are stale / take a moment to update"

The input manager runs in Update, so input is at most one frame stale. In a 60 FPS game, that's 16 ms — usually unnoticeable. If you're seeing larger delays, it's probably the vehicle's input smoothing settings (clutch inertia, steer sensitivity), not the input system itself.

"I want to rebind keys at runtime"

The Input System supports interactive rebinding. Search the Unity Input System docs for "rebinding UI." This is non-trivial to set up but Unity provides a sample. RCC doesn't ship its own rebinding UI but works fine with one you build.

Adding a New Input

If you want to add a custom action (e.g., "Honk Horn" bound to H):

  1. Open RCC_InputActions.inputactions.
  2. In the Vehicle action map, click + to add a new action.
  3. Name it Horn.
  4. Set its Action Type to Button.
  5. Add a binding (e.g., Keyboard / H).
  6. Save.
  7. In your own script:
using UnityEngine.InputSystem;

public class HornHandler : MonoBehaviour {
    private RCC_InputActions actions;

    void Awake() {
        actions = new RCC_InputActions();
    }

    void OnEnable() {
        actions.Vehicle.Enable();
        actions.Vehicle.Horn.performed += OnHorn;
    }

    void OnDisable() {
        actions.Vehicle.Horn.performed -= OnHorn;
        actions.Vehicle.Disable();
    }

    void OnHorn(InputAction.CallbackContext ctx) {
        Debug.Log("HONK!");
    }
}

You're not modifying RCC — your script is just another consumer of the same Input Actions asset.

Next Steps