Input System Package
一、重要前提:启用新输入系统(必做!)
安装完Input System后,Unity会弹框提示你重启Unity并启用新输入系统,如果没弹框,手动设置:
- 打开
Edit -> Project Settings -> Player - 在
Other Settings里找到 Active Input Handling - 选择 Input System Package (New)
- 点击重启Unity,配置生效
⚠️ 注意:新旧输入系统默认互斥,启用新系统后,旧的
Input.GetKey/Input.GetAxis这类API会失效,二选一即可。
二、方案一:纯代码直接调用(推荐!最简最快,90%场景够用)
这种方式无需创建任何Input Action资产、无需绑定、无需配置,直接在脚本里写代码就能获取键盘输入,和旧输入系统的写法最接近,新手首选、开发效率最高,也是最常用的方式。
✅ 核心API:Keyboard.current
Keyboard.current 是Input System的核心键盘实例对象,通过它可以获取任意键盘按键的所有状态,全局唯一,直接调用即可。
🔸 核心按键状态API(3种最常用,必记)
所有键盘按键都支持这3个核心状态判断,用法完全统一,格式:Keyboard.current.按键名称.状态
.wasPressedThisFrame→ 【按下瞬间】:按键在当前帧被按下,只会触发1次(比如:按下空格跳一下、按下J攻击一次).wasReleasedThisFrame→ 【抬起瞬间】:按键在当前帧被松开,只会触发1次(比如:松开Shift取消冲刺).isPressed→ 【持续按住】:按键当前处于按住状态,每一帧都会触发(比如:按住WASD移动、按住空格持续上浮)
✅ 完整代码示例(复制即用,含移动+按键触发+持续按住)
using UnityEngine;
// 必须引入这个命名空间!缺一不可
using UnityEngine.InputSystem;
public class KeyboardInputTest : MonoBehaviour
{
[Header("移动速度")]
public float moveSpeed = 5f;
private Vector3 moveDir;
void Update()
{
// ========== 1. 核心:获取键盘实例 ==========
Keyboard keyboard = Keyboard.current;
if (keyboard == null) return; // 保险判断:防止无键盘设备时报错
// ========== 2. 【持续按住】- 典型场景:WASD移动 ==========
moveDir = Vector3.zero;
if (keyboard.wKey.isPressed) moveDir += Vector3.forward;
if (keyboard.sKey.isPressed) moveDir += Vector3.back;
if (keyboard.aKey.isPressed) moveDir += Vector3.left;
if (keyboard.dKey.isPressed) moveDir += Vector3.right;
// 移动归一化,防止斜向移动速度翻倍
transform.Translate(moveDir.normalized * moveSpeed * Time.deltaTime);
// ========== 3. 【按下瞬间】- 典型场景:按下空格跳跃、按下J攻击 ==========
if (keyboard.spaceKey.wasPressedThisFrame)
{
Debug.Log("空格被按下了!跳跃/触发技能");
}
if (keyboard.jKey.wasPressedThisFrame)
{
Debug.Log("J键按下!普通攻击");
}
// ========== 4. 【抬起瞬间】- 典型场景:松开Shift取消加速 ==========
if (keyboard.leftShiftKey.wasReleasedThisFrame)
{
Debug.Log("左Shift松开!取消冲刺");
moveSpeed = 5f; // 恢复原速
}
if (keyboard.leftShiftKey.isPressed)
{
moveSpeed = 10f; // 按住Shift加速
}
}
}
三、方案二:Input Action 可视化配置(进阶方案,推荐团队/大型项目)
这是Input System的标准/推荐用法,也是设计初衷:输入逻辑和业务逻辑完全解耦,支持可视化配置、一键切换键鼠/手柄/触屏,支持组合键、多按键映射同一个行为,适合中大型项目/团队协作。
✅ 核心步骤(4步搞定,清晰易懂)
Step 1:创建 Input Action 资产文件
在Project窗口右键 → Input Actions → 创建一个资产文件(比如命名为 PlayerInputActions)
Step 2:可视化配置按键映射
双击刚创建的PlayerInputActions,打开配置窗口,操作如下:
- 左侧点击
+→ 新建一个Action Map(比如命名为Player,代表玩家的所有输入行为) - 选中
Player→ 右侧点击+→ 新建Action(配置具体行为,比如:Move移动、Jump跳跃、Attack攻击) - 配置Action的绑定:
- 选中
Move→ 点击右侧+→Add Binding→ 选择Keyboard→ 绑定W/A/S/D或↑/←/↓/→ - 选中
Jump→ 绑定Space 空格 - 选中
Attack→ 绑定J/K(可以绑定多个按键)
- 选中
- 保存配置窗口(Ctrl+S)
Step 3:脚本中绑定并使用 Input Action
有两种绑定方式,这里推荐最简单的C#脚本直接绑定(还有一种是通过PlayerInput组件绑定,更傻瓜式,文末补充),脚本如下:
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerInputActionTest : MonoBehaviour
{
// 拖拽步骤1创建的Input Actions资产文件到这里
public PlayerInputActions playerInputActions;
private void Awake()
{
// 启用Input Action映射(必须!否则无法响应输入)
playerInputActions.Enable();
}
private void Update()
{
// 1. 获取【移动】输入 - 直接返回Vector2向量(x=左右,y=前后),无需手动判断WASD!
Vector2 moveVec = playerInputActions.Player.Move.ReadValue<Vector2>();
transform.Translate(new Vector3(moveVec.x, 0, moveVec.y) * 5f * Time.deltaTime);
// 2. 判断【跳跃】按下瞬间
if (playerInputActions.Player.Jump.WasPressedThisFrame())
{
Debug.Log("跳跃触发");
}
// 3. 判断【攻击】按下瞬间
if (playerInputActions.Player.Attack.WasPressedThisFrame())
{
Debug.Log("攻击触发");
}
}
// 必写:销毁时禁用,防止内存泄漏
private void OnDestroy()
{
playerInputActions.Disable();
}
}
Step 4:挂载脚本并赋值
把脚本挂载到场景物体上 → 在Inspector面板,把创建的PlayerInputActions资产拖拽到脚本的playerInputActions字段 → 运行即可生效。
✅ 这种方案的核心优势
- 输入和逻辑解耦:改按键不用改代码,直接在配置窗口改绑定即可
- 扩展性极强:一键添加手柄支持,手柄的左摇杆自动映射到
Move,无需改代码 - 支持组合键、按键优先级、多按键映射,适合复杂输入逻辑
四、最全常用键盘按键名称(API速查表,必收藏!)
Keyboard.current.xxx 中的 xxx 就是按键名称,严格大小写,下面是开发中99%会用到的按键,直接复制使用:
✅ 方向/移动键
wKey/aKey/sKey/dKey 、 upArrowKey(↑)、leftArrowKey(←)、downArrowKey(↓)、rightArrowKey(→)
✅ 功能键
spaceKey(空格)、enterKey(回车)、escapeKey(ESC)、tabKey(Tab)、backspaceKey(退格)
✅ 字母键(A-Z)
aKey ~ zKey (例:jKey、kKey、qKey、eKey)
✅ 数字键(键盘顶部+小键盘)
顶部数字:digit1Key(1) ~ digit9Key(9)、digit0Key(0)
小键盘数字:numpad1Key ~ numpad9Key、numpad0Key
✅ 修饰键(组合键常用)
leftShiftKey(左Shift)、rightShiftKey(右Shift)、leftCtrlKey(左Ctrl)、rightCtrlKey(右Ctrl)
leftAltKey(左Alt)、rightAltKey(右Alt)、leftMetaKey(Win键)、rightMetaKey(Mac Cmd)
✅ 符号键
minusKey(-)、equalsKey(=)、commaKey(,)、periodKey(.)、slashKey(/)、backslashKey()
五、常见问题 & 避坑指南(必看!解决90%报错)
❌ 报错1:The name 'Keyboard' does not exist in the current context
✅ 解决:脚本顶部忘记引入命名空间 → 加上这行:using UnityEngine.InputSystem;
❌ 报错2:Keyboard.current 一直是null,按键无响应
✅ 解决:没有启用新输入系统 → 回到本文最顶部,重新配置 Player -> Active Input Handling = Input System Package 并重启Unity
❌ 问题3:按下按键触发多次,想要只触发一次
✅ 解决:不要用 .isPressed 做单次触发逻辑,改用 .wasPressedThisFrame,这个API是「帧级触发」,只会在按下的那一帧返回true。
❌ 问题4:斜向移动时速度比单方向快一倍
✅ 解决:对移动向量做归一化处理 → moveDir.normalized,参考方案一的代码示例。
❌ 问题5:Input Action 配置后无响应
✅ 解决:必须调用 .Enable() 启用,在Awake()中启用,OnDestroy()中禁用,参考方案二的代码。
六、新旧输入系统 核心API对比(快速迁移必看)
如果你是从旧的Input系统迁移过来的,这个对比表能让你瞬间对应上,无缝切换:
| 旧输入系统(Input) | 新输入系统(Input System) | 功能说明 |
|---|---|---|
Input.GetKeyDown(KeyCode.Space) |
Keyboard.current.spaceKey.wasPressedThisFrame |
按键按下瞬间 |
Input.GetKeyUp(KeyCode.Space) |
Keyboard.current.spaceKey.wasReleasedThisFrame |
按键抬起瞬间 |
Input.GetKey(KeyCode.W) |
Keyboard.current.wKey.isPressed |
按键持续按住 |
Input.GetAxis("Horizontal") |
Keyboard.current.dKey.isPressed - Keyboard.current.aKey.isPressed |
水平轴输入 |
Input.GetAxis("Vertical") |
Keyboard.current.wKey.isPressed - Keyboard.current.sKey.isPressed |
垂直轴输入 |
✅ 总结(两种方案怎么选?)
- 纯代码方案(
Keyboard.current):新手首选、快速开发首选,代码简洁、无需配置、上手即用,适合独立开发、小型项目、快速原型验证,90%的个人开发场景够用。 - Input Action方案:进阶首选、团队/大型项目首选,输入与逻辑解耦、扩展性极强、支持多设备无缝切换,是Input System的标准用法,稍微学一点配置成本,后期收益巨大。
两种方案的核心按键状态判断逻辑是一致的:按下瞬间/抬起瞬间/持续按住,掌握这三个核心逻辑,就能搞定所有键盘输入需求啦!