Skip to content

输入系统

unity-input-system-overview

1. 输入系统到底管什么

输入系统负责把“玩家按了什么”变成“游戏要做什么”。

键盘 W        -> Move
手柄左摇杆    -> Move
空格键        -> Jump
手柄 A 键     -> Jump
鼠标左键      -> Fire
触摸按钮      -> Fire

核心思想是:不要让角色移动代码关心“到底是 W 还是摇杆”,而是只关心“玩家想移动”。

2. Unity 有两套输入系统

旧系统:

Input.GetKeyDown(KeyCode.Space);
Input.GetAxis("Horizontal");

它叫 Legacy Input Manager。老教程很多会用它,简单,但不适合复杂项目。Unity 官方现在推荐新项目用新的 Input System Package,旧系统主要用于维护老项目。

新系统:

Input Action Asset
Action Map
Action
Binding
PlayerInput

它更适合:

键鼠 + 手柄
移动端触摸
玩家改键
多人游戏
UI 和游戏输入分离
复杂按键,比如长按、双击、蓄力

3. 新输入系统的核心词

你先背这条链:

Device -> Control -> Binding -> Action -> Action Map -> 代码

含义是:

Device:设备,比如 Keyboard、Mouse、Gamepad
Control:设备上的具体控件,比如 space、leftStick、leftButton
Binding:把 Control 绑定到 Action,例如 <Keyboard>/space -> Jump
Action:游戏行为,比如 Move、Jump、Fire
Action Map:一组 Action,比如 Gameplay、UI、Vehicle
Input Action Asset:保存这些配置的 .inputactions 文件

4. 最推荐的新手工作流

  1. 安装或启用 Input System

  2. 创建 PlayerControls.inputactions

  3. 建一个 Action Map:Gameplay

  4. 添加 Actions:

    Move    Value / Vector2
    Jump    Button
    Fire    Button
    Pause   Button
  5. Move 加绑定:

    c
    2D Vector Composite: WASD
    2D Vector Composite: Arrow Keys
    <Gamepad>/leftStick
  6. Jump 加绑定:

    c
    <Keyboard>/space
    <Gamepad>/buttonSouth
  7. 玩家物体上挂 PlayerInput

  8. .inputactions 拖到 PlayerInputActions

  9. Default MapGameplay

  10. Behavior 推荐新手先选 Invoke Unity Events

5. 一个完整移动案例

c
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    [SerializeField] private float moveSpeed = 5f;

    private Vector2 moveInput;

    public void OnMove(InputAction.CallbackContext context)
    {
        moveInput = context.ReadValue<Vector2>();
    }

    public void OnJump(InputAction.CallbackContext context)
    {
        if (!context.performed) return;

        Debug.Log("Jump");
    }

    private void Update()
    {
        Vector3 move = new Vector3(moveInput.x, 0f, moveInput.y);
        transform.Translate(move * moveSpeed * Time.deltaTime, Space.World);
    }
}

然后在 PlayerInput 的 Events 里绑定:

c
Gameplay / Move -> PlayerController.OnMove
Gameplay / Jump -> PlayerController.OnJump

重点:Move 不要只在按下瞬间移动一次。正确做法是把输入值存到 moveInput,然后在 UpdateFixedUpdate 里持续使用。

6. started、performed、canceled 是什么

一个 Action 会经历阶段:

c
started    开始了
performed 触发成功
canceled  结束或取消

普通跳跃通常只关心:

c
if (context.performed)
{
    Jump();
}

长按蓄力就会用到三个阶段:

c
started:显示蓄力条
performed:蓄力成功,发射
canceled:松太早,取消蓄力

7. Interactions:按键模式

Interaction 决定“怎样按才算触发”。

常见有:

c
Press      按下
Hold       长按
Tap        短按
SlowTap    慢按
MultiTap   多次点击

例子:

c
Fire + Tap       -> 普通射击
Fire + Hold      -> 蓄力射击
Dash + MultiTap  -> 双击冲刺

8. Processors:处理输入值

Processor 会修改输入值。

常见有:

c
Deadzone    摇杆死区
Normalize   归一化
Invert      反转
Scale       缩放
Clamp       限制范围

比如玩家觉得视角上下反了,就可以对 Look 的 Y 轴做 Invert Vector2

9. Action Map:不同状态用不同输入表

你可以建多个 Action Map:

c
Gameplay:Move、Jump、Fire、Pause
UI:Navigate、Submit、Cancel
Vehicle:Steer、Brake、Boost
Menu:Confirm、Back

暂停时切到 UI:

c
using UnityEngine.InputSystem;

public class InputModeSwitcher : MonoBehaviour
{
    [SerializeField] private PlayerInput playerInput;

    public void OpenPauseMenu()
    {
        playerInput.SwitchCurrentActionMap("UI");
    }

    public void ClosePauseMenu()
    {
        playerInput.SwitchCurrentActionMap("Gameplay");
    }
}

这比到处写 if (isPaused) return; 干净很多。

10. 常见 API 速查

c
context.ReadValue<Vector2>();
context.performed;
context.started;
context.canceled;
playerInput.SwitchCurrentActionMap("UI");
playerInput.ActivateInput();
playerInput.DeactivateInput();
Keyboard.current.spaceKey.wasPressedThisFrame;
Mouse.current.position.ReadValue();
Gamepad.current.leftStick.ReadValue();

前两组是项目里更常用的高层写法。最后一组是直接读设备,适合调试或特殊情况。

11. UI 输入

如果你用新输入系统,UI 里通常要用:

c
Input System UI Input Module

而不是旧的:

c
Standalone Input Module

否则会出现按钮不能点、键盘导航不工作之类的问题。

12. 最容易犯的错

c
忘了启用 Input System 或 Active Input Handling 没切对
PlayerInput 没拖 .inputactions
Default Action Map 没选
Move 是 Vector2,却绑成普通 Button
代码签名和 PlayerInput Behavior 不匹配
Action 没 Enable,手写 InputAction 时尤其常见
UI 还在用旧 Standalone Input Module
performed 里直接移动,导致角色只动一下
重复注册回调,导致一次按键触发多次

13. 你现在该怎么学

学习顺序建议:

c
先会旧系统:Input.GetKeyDown / GetAxis,看懂老教程
重点学新系统:Input Action Asset + PlayerInput
先做 Move / Jump / Fire
再学 UI 和 Action Map 切换
最后学 Hold、Tap、改键、多人

记住一句话:

c
旧输入系统是在问“哪个键被按了”。
新输入系统是在问“玩家想做什么动作”。

参考资料:Unity 官方 Input System PackageLegacy InputActionsPlayerInputBindingsInteractionsProcessors

文章评价

读完这篇,留下你的看法

暂无审核通过的评价。

登录账号后才能评价。

本站访客数0总站访问量0本页访问量0