PluginBench
Skill
Pass
Audit score 90

unity-input-system

gamedev-skills/awesome-gamedev-agent-skills

Wire player input in Unity 6.3 LTS with action-based, device-agnostic Input System package.

What is unity-input-system?

Set up input handling in Unity using the modern Input System package (com.unity.inputsystem). Create .inputactions assets with action maps, bind controls, and read input via PlayerInput components or direct code callbacks. Use this when setting up movement, jump, fire, or other player controls that need to work across keyboard, gamepad, and touch.

  • Create and configure .inputactions assets with action maps and control schemes
  • Wire PlayerInput components with Send Messages, Broadcast, or C# Events behaviors
  • Read input values directly in code via InputActionReference or InputActionAsset
  • Switch action maps for context changes (gameplay ↔ UI/menu)
  • Handle both continuous values (stick/WASD) and edge events (button presses)
  • Verify input with the Input Debugger and troubleshoot device detection

How to install unity-input-system

npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill unity-input-system
Prerequisites
  • Unity 6.3 LTS or compatible version
  • Input System package (com.unity.inputsystem 1.x) installed in Packages/manifest.json
  • Active Input Handling set to 'Input System Package (New)' or 'Both' in Project Settings → Player
Claude Code
Cursor
Windsurf
Cline

How to use unity-input-system

  1. 1.Create a .inputactions asset (right-click → Create → Input Actions)
  2. 2.Add an action map (e.g. 'Gameplay') and actions (Move as Vector2, Jump as Button, Fire as Button)
  3. 3.Bind actions to controls: WASD/stick for Move, Space/gamepad button for Jump, etc.
  4. 4.Choose your reading method: drop a PlayerInput component on the player (Send Messages) or reference actions in code (InputActionReference)
  5. 5.If using PlayerInput with Send Messages, create handler methods (OnMove, OnJump) on the same GameObject
  6. 6.If reading directly, call action.Enable() in OnEnable() and action.Disable() in OnDisable()
  7. 7.Use ReadValue<T>() for continuous values (Vector2 stick) and performed callbacks for button presses
  8. 8.Test with Window → Analysis → Input Debugger to confirm devices and action firing

Use cases

Good for
  • Setting up WASD movement and jump input for a player character
  • Binding gamepad stick and buttons alongside keyboard controls in a single action map
  • Switching between gameplay and pause-menu input contexts without scattered if-checks
  • Reading a Vector2 move value every frame and applying it to a Rigidbody
  • Handling button presses (fire, interact) via performed callbacks instead of per-frame polling
Who it's for
  • Game programmers implementing player input in Unity 6.3 LTS
  • Designers setting up input via PlayerInput components and action maps
  • Gameplay engineers wiring movement, combat, and interaction systems
  • Developers migrating from legacy Input Manager (GetAxis/GetKey) to the new Input System

unity-input-system FAQ

What's the difference between PlayerInput and reading actions directly in code?

PlayerInput is designer-friendly and auto-enables actions; it calls handler methods by name (Send Messages) or fires events. Direct code reading (InputActionReference/InputActionAsset) gives you full control but requires manual Enable()/Disable(). Use PlayerInput for single-player/local-coop; use direct reading for systems, tools, or complex multi-player logic.

Why is my input not working at all?

Check two things: (1) Active Input Handling in Project Settings → Player must be 'Input System Package (New)' or 'Both', not 'Input Manager (Old)'. (2) You must call .Enable() on any InputAction or action map you reference directly; PlayerInput auto-enables, but raw actions do not.

How do I handle button presses vs. continuous stick values?

For continuous values (stick, WASD), use ReadValue<Vector2>() every frame in Update(). For button presses (jump, fire), use the performed callback or WasPressedThisFrame(); reading a button with ReadValue() returns 0 because presses are edge events, not per-frame values.

How do I switch between gameplay and UI input?

Create separate action maps (Gameplay, UI) in your .inputactions asset. In code, disable one map and enable the other: actions.FindActionMap('Gameplay').Disable(); actions.FindActionMap('UI').Enable(). This avoids scattered if-checks throughout your handlers.

Can I support keyboard, gamepad, and touch from one set of actions?

Yes. In the .inputactions asset, create control schemes (Keyboard&Mouse, Gamepad, Touch) and bind the same action to controls from each scheme. The Input System automatically picks the active device. Verify device detection in the Input Debugger.

Full instructions (SKILL.md)

Source of truth, from gamedev-skills/awesome-gamedev-agent-skills.


name: unity-input-system description: > Wire player input in Unity 6.3 LTS with the Input System package: Input Actions, action maps, the PlayerInput component, and reading values via callbacks or polling. Use when the project has a .inputactions asset or com.unity.inputsystem, or when the user mentions the Unity Input System, InputAction, action maps, PlayerInput, control schemes, or rebinding.

Unity Input System (new)

Read input through Unity's Input System package (com.unity.inputsystem, 1.x) — action-based, device-agnostic, rebindable. Targets Unity 6.3 LTS. This is the modern replacement for the legacy Input.GetAxis/Input.GetKey Input Manager.

When to use

  • Use when setting up movement/jump/fire input, defining an .inputactions asset with action maps and control schemes, wiring a PlayerInput component, reading a Vector2 stick/WASD value, or handling gamepad + keyboard + touch from one set of actions.
  • Use when Packages/manifest.json contains com.unity.inputsystem or the project has an *.inputactions asset.

When not to use: rebindable-control architecture across engines → input-systems (this skill is the Unity-specific API). Moving the character once you have the input vector → unity-physics / unity-csharp-scripting.

Core workflow

  1. Check Active Input Handling (Project Settings → Player). The package only receives input when this is Input System Package (New) or Both. Both is required if any old Input.GetAxis code remains.
  2. Create an .inputactions asset. Add an action map (e.g. Gameplay), add actions (Move = Value/Vector2, Jump = Button, Fire = Button), and bind them to controls and composite bindings (WASD = 2D Vector composite).
  3. Choose how to read it:
    • PlayerInput component (designer-friendly) — drop it on the player, point it at the asset, pick a Behavior (Send Messages / Broadcast / Invoke Unity Events / Invoke C# Events). Best for single/local-coop players.
    • Direct in code (InputActionReference / InputActionAsset) — most control; you Enable() actions and read them. Best for systems and tools.
  4. Enable the actions/maps you read. PlayerInput enables its default map automatically; actions you reference yourself must be .Enable()d (and disabled on teardown).
  5. Switch action maps for context (gameplay ↔ UI/menu) instead of guarding every handler.
  6. Verify with the Input Debugger (Window → Analysis → Input Debugger) to confirm devices and that actions fire.

Patterns

1. PlayerInput with "Send Messages" (handlers on the same GameObject)

using UnityEngine;
using UnityEngine.InputSystem;

// PlayerInput (Behavior = Send Messages) calls On<ActionName>(InputValue) by name.
public class PlayerInputReceiver : MonoBehaviour
{
    private Vector2 _move;

    private void OnMove(InputValue value) => _move = value.Get<Vector2>();   // Move action
    private void OnJump(InputValue value) { if (value.isPressed) Jump(); }   // Button action

    private void Update() { /* drive movement from _move */ }
    private void Jump() { }
}

2. Reading an action directly in code (polling a value)

using UnityEngine;
using UnityEngine.InputSystem;

public class DirectMover : MonoBehaviour
{
    [SerializeField] private InputActionReference moveAction;  // assign the Move action

    private void OnEnable()  => moveAction.action.Enable();    // REQUIRED or it reads zero
    private void OnDisable() => moveAction.action.Disable();

    private void Update()
    {
        Vector2 move = moveAction.action.ReadValue<Vector2>(); // continuous value
        transform.Translate(new Vector3(move.x, 0, move.y) * (5f * Time.deltaTime));
    }
}

3. Event callbacks + switching action maps (gameplay ↔ UI)

[SerializeField] private InputActionAsset actions;

private void OnEnable()
{
    actions.FindAction("Gameplay/Fire").performed += OnFire;  // edge event: fires once
    actions.FindActionMap("Gameplay").Enable();
}
private void OnDisable() => actions.FindAction("Gameplay/Fire").performed -= OnFire;

private void OnFire(InputAction.CallbackContext ctx) => Shoot();  // ctx.ReadValue<T>() if needed

private void OpenPauseMenu()                       // change context, don't sprinkle if-checks
{
    actions.FindActionMap("Gameplay").Disable();
    actions.FindActionMap("UI").Enable();
}
private void Shoot() { }

Pitfalls

  • No input at all → either Active Input Handling is still Input Manager (Old), or you forgot to Enable() the action/map. PlayerInput auto-enables; raw InputActions do not.
  • InvalidOperationException about the old input backend → some script still calls Input.GetAxis/Input.GetKey while Active Input Handling is New. Port it or set Both.
  • Buttons read as 0 with ReadValue → button presses are edge events; use the performed callback (or WasPressedThisFrame()), not per-frame ReadValue for triggers.
  • Send Messages handlers never fire → the receiving script must be on the same GameObject as the PlayerInput; Broadcast Messages reaches children too.
  • Leaking subscriptions → unsubscribe (-=) in OnDisable; re-subscribing in OnEnable without unsubscribing doubles up handlers.
  • Touch/gamepad not detected → enable the matching control scheme and confirm the device in the Input Debugger; the Vector2 composite needs all four bindings set.

References

  • For interactive control rebinding (PerformInteractiveRebinding), saving/loading bindings as JSON, and local multiplayer with PlayerInputManager, read references/rebinding.md.
  • Primary docs: Unity Manual "Input System" (https://docs.unity3d.com/Manual/com.unity.inputsystem.html).

Related skills

  • input-systems — engine-agnostic input architecture (rebinding, buffering, multi-device).
  • unity-csharp-scripting — the MonoBehaviour these handlers live in.
  • unity-physics — applying the input vector to a Rigidbody.