unity-input-system

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Unity Input System (new)

Unity Input System(新版)

Read input through Unity's Input System package (
com.unity.inputsystem
, 1.x) — action-based, device-agnostic, rebindable. Targets Unity 6. This is the modern replacement for the legacy
Input.GetAxis
/
Input.GetKey
Input Manager.
通过Unity的Input System包
com.unity.inputsystem
,1.x版本)读取输入——基于动作、设备无关、支持重新绑定。适用于Unity 6,是旧版
Input.GetAxis
/
Input.GetKey
输入管理器的现代替代方案。

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
.
  • 当你需要设置移动/跳跃/射击输入、定义包含动作映射和控制方案的
    .inputactions
    资源、关联
    PlayerInput
    组件、读取
    Vector2
    摇杆/WASD输入值,或者通过一组动作同时处理游戏手柄+键盘+触摸输入时,可使用本内容。
  • Packages/manifest.json
    文件包含
    com.unity.inputsystem
    ,或项目中存在
    *.inputactions
    资源时,可使用本内容。
不适用场景:跨引擎的可重新绑定控制架构 → 参考
input-systems
(本技能是Unity专属API)。获取输入向量后控制角色移动 → 参考
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.
  1. 检查激活输入处理设置(项目设置→玩家)。仅当该选项设置为
    Input System Package (New)
    Both
    时,本包才能接收输入。如果项目中仍存在旧版
    Input.GetAxis
    代码,则必须设置为
    Both
  2. 创建
    .inputactions
    资源
    。添加动作映射(例如
    Gameplay
    ),添加动作(
    Move
    =值/Vector2,
    Jump
    =按钮,
    Fire
    =按钮),并将它们绑定到控件和复合绑定(WASD=2D向量复合绑定)。
  3. 选择读取方式
    • PlayerInput
      组件
      (适合设计师)——将其添加到玩家对象上,关联到.inputactions资源,选择一种行为(发送消息/广播/调用Unity事件/调用C#事件)。最适合单人/本地合作玩家。
    • 代码直接读取
      InputActionReference
      /
      InputActionAsset
      )——控制度最高;你需要调用
      Enable()
      启用动作并读取输入。最适合系统和工具开发。
  4. 启用你要读取的动作/映射
    PlayerInput
    会自动启用其默认映射;你自行引用的动作必须调用
    .Enable()
    (并在销毁时禁用)。
  5. 根据上下文切换动作映射(游戏玩法↔UI/菜单),无需在每个处理程序中添加条件判断。
  6. 验证输入:使用输入调试器(窗口→分析→输入调试器)确认设备连接状态和动作触发情况。

Patterns

常见模式

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

1. 使用
PlayerInput
的“发送消息”模式(处理程序位于同一游戏对象上)

csharp
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() { }
}
csharp
using UnityEngine;
using UnityEngine.InputSystem;

// PlayerInput(行为=发送消息)会按名称调用On<ActionName>(InputValue)方法。
public class PlayerInputReceiver : MonoBehaviour
{
    private Vector2 _move;

    private void OnMove(InputValue value) => _move = value.Get<Vector2>();   // Move动作
    private void OnJump(InputValue value) { if (value.isPressed) Jump(); }   // 按钮动作

    private void Update() { /* 基于_move变量驱动移动 */ }
    private void Jump() { }
}

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

2. 代码中直接读取动作(轮询值)

csharp
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));
    }
}
csharp
using UnityEngine;
using UnityEngine.InputSystem;

public class DirectMover : MonoBehaviour
{
    [SerializeField] private InputActionReference moveAction;  // 关联Move动作

    private void OnEnable()  => moveAction.action.Enable();    // 必须调用,否则读取值为0
    private void OnDisable() => moveAction.action.Disable();

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

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

3. 事件回调 + 切换动作映射(游戏玩法↔UI)

csharp
[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() { }
csharp
[SerializeField] private InputActionAsset actions;

private void OnEnable()
{
    actions.FindAction("Gameplay/Fire").performed += OnFire;  // 边缘事件:仅触发一次
    actions.FindActionMap("Gameplay").Enable();
}
private void OnDisable() => actions.FindAction("Gameplay/Fire").performed -= OnFire;

private void OnFire(InputAction.CallbackContext ctx) => Shoot();  // 如需获取值可使用ctx.ReadValue<T>()

private void OpenPauseMenu()                       // 切换上下文,无需添加大量条件判断
{
    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
    InputAction
    s 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.
  • 完全无法获取输入 → 要么激活输入处理仍设置为
    Input Manager (Old)
    ,要么你忘记调用
    Enable()
    启用动作/映射。
    PlayerInput
    会自动启用;原生
    InputAction
    不会。
  • 出现关于旧输入后端的
    InvalidOperationException
    异常
    → 当激活输入处理设置为
    New
    时,仍有脚本调用
    Input.GetAxis
    /
    Input.GetKey
    。请迁移这些代码,或将设置改为
    Both
  • 使用
    ReadValue
    读取按钮值为0
    → 按钮按下是边缘事件;应使用
    performed
    回调(或
    WasPressedThisFrame()
    ),而非每帧轮询
    ReadValue
    来检测触发。
  • “发送消息”处理程序从未触发 → 接收脚本必须与
    PlayerInput
    位于同一游戏对象上;“广播消息”可传递给子对象。
  • 订阅泄漏 → 在
    OnDisable
    中取消订阅(
    -=
    );如果在
    OnEnable
    中重新订阅却未先取消,会导致处理程序重复绑定。
  • 触摸/游戏手柄未被检测到 → 启用对应的控制方案,并在输入调试器中确认设备状态;Vector2复合绑定需要设置全部四个绑定项。

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
    ).
  • 如需了解交互式控制重新绑定
    PerformInteractiveRebinding
    )、以JSON格式保存/加载绑定,以及使用
    PlayerInputManager
    实现本地多人游戏,请阅读
    references/rebinding.md
  • 官方文档:Unity手册「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.
  • input-systems
    —— 引擎无关的输入架构(重新绑定、缓冲、多设备支持)。
  • unity-csharp-scripting
    —— 这些处理程序所在的MonoBehaviour相关技能。
  • unity-physics
    —— 将输入向量应用到Rigidbody的相关技能。