Quick answer: The PlayerInput component auto-switches between control schemes only when Auto-Switch is enabled in its inspector. Without it, the active scheme stays whatever it was at startup. Subscribe to onControlsChanged to react to switches, and call SwitchCurrentControlScheme manually if you need to force a swap.

Here is how to fix Unity New Input System control schemes that refuse to switch when the player picks up a controller. Keyboard works on game start. Plug in a gamepad, press buttons, and the action callbacks come through — but PlayerInput.currentControlScheme still says “Keyboard & Mouse.” Your on-screen prompts stay on keyboard glyphs. The fix is usually a single checkbox in the inspector, or a missing SwitchCurrentControlScheme call.

The Symptom

The PlayerInput on your character is wired up correctly. Keyboard W/A/S/D moves. So does the gamepad left stick. But the prompt UI never updates from keyboard glyphs to controller glyphs. PlayerInput.currentControlScheme is stuck on its initial value. onControlsChanged never fires.

What Causes This

Auto-Switch disabled. The PlayerInput inspector has a checkbox labeled Auto-Switch (under the Notification Behavior dropdown). When unchecked, the component does not change schemes even if input from a different device arrives.

Multiplayer lock-in. If you have multiple PlayerInput components (local co-op), the system pairs each one to specific devices and refuses to switch on its own. This is by design but surprising for solo developers who just want device-agnostic input.

Scheme name mismatch. When calling SwitchCurrentControlScheme, the string must match exactly what is defined in the .inputactions asset. Case-sensitive.

Device not paired. Schemes can list devices as required or optional. If your gamepad is not paired with the user, the scheme cannot activate even when input arrives.

The Fix

Step 1: Enable Auto-Switch in the inspector. Select your PlayerInput component, expand Behavior, and check Auto-Switch. This is the simplest fix for single-player games.

Step 2: Subscribe to onControlsChanged for UI updates.

using UnityEngine;
using UnityEngine.InputSystem;

[RequireComponent(typeof(PlayerInput))]
public class InputDeviceWatcher : MonoBehaviour
{
    private PlayerInput playerInput;

    void Awake() { playerInput = GetComponent<PlayerInput>(); }

    void OnEnable()  { playerInput.onControlsChanged += OnControlsChanged; }
    void OnDisable() { playerInput.onControlsChanged -= OnControlsChanged; }

    void OnControlsChanged(PlayerInput pi)
    {
        Debug.Log($"Active scheme: {pi.currentControlScheme}");
        UpdatePromptGlyphs(pi.currentControlScheme);
    }
}

Step 3: Force a switch when needed.

// Swap to gamepad scheme using the connected gamepad device
if (Gamepad.current != null)
{
    playerInput.SwitchCurrentControlScheme("Gamepad", Gamepad.current);
}

Pass the device explicitly so the scheme has something to pair with. Pass multiple devices for schemes requiring keyboard plus mouse:

playerInput.SwitchCurrentControlScheme("Keyboard&Mouse",
    Keyboard.current, Mouse.current);

Step 4: Confirm scheme names. Open the .inputactions asset, click the Control Schemes dropdown at the top, and note the exact names. Use them as constants in code:

const string SCHEME_KBM     = "Keyboard&Mouse";
const string SCHEME_GAMEPAD = "Gamepad";

Step 5: For listen-for-any-device, use InputUser. If you want the player to start the game without a paired device and pair on first input, use the InputUser API:

InputUser user = InputUser.PerformPairingWithDevice(Gamepad.current);
user.AssociateActionsWithUser(actionAsset);
user.ActivateControlScheme("Gamepad");

Multiplayer Considerations

In split-screen, each PlayerInput owns specific devices. Auto-Switch is meaningless because each player’s scheme is fixed to their assigned devices. Use PlayerInputManager with Join Action to pair devices to players as they join.

UI Glyphs Best Practice

Cache a dictionary of glyph sprites keyed by scheme name. Update once per scheme change, not per frame. Reading currentControlScheme in Update is safe but unnecessary — onControlsChanged already gives you the events.

“Auto-Switch checkbox handles 90% of cases. The other 10% is explicit SwitchCurrentControlScheme with the right device array.”

Related Issues

For input not arriving at all, see New Input System Actions Not Updating. For UI failures, see New Input System UI Not Working.

Auto-Switch on. Subscribe to onControlsChanged. Match scheme names exactly. Done.