手把手拆解Unity新输入系统:从零到懂的完整指南

📅 2026/8/7 9:33:52
手把手拆解Unity新输入系统:从零到懂的完整指南
前言为什么你会不懂如果你读完前面的介绍文章还是一头雾水别自责——这不是你的问题是新输入系统真的很绕。它引入了太多新概念Device、Action、Binding、Action Map、Control Scheme、Composite、Interaction、Processor……这些词单独看都能理解但它们怎么串在一起、每个到底做什么、代码到底该怎么写——教程里往往一笔带过让人云里雾里。今天我们抛开高大上的架构描述用最具体的例子一步步把每个概念拆开揉碎讲清楚。看完这篇文章你不仅能懂还能自己动手写。第一步先把新系统装上新输入系统不是Unity内置的你需要手动安装打开Window Package Manager左上角切换到Unity Registry搜索“Input System”点击Install安装后Unity会弹窗问你要切换到新输入系统吗选Yes。Unity会重启之后旧的Input.GetKey就失效了除非你选择Both模式同时启用两套。设置位置在Edit Project Settings Player Active Input HandlingInput Manager (Old)只用旧系统Input System Package (New)只用新系统Both两套同时启用推荐初学者过渡时选这个第二步认识那个最简单的例子我们从一个最原始的例子开始——按空格键让方块跳起来。在旧系统里代码是这样的voidUpdate(){if(Input.GetKeyDown(KeyCode.Space)){rb.AddForce(Vector3.up*5,ForceMode.Impulse);}}在新系统里最直译的写法是这样的usingUnityEngine.InputSystem;voidUpdate(){if(Keyboard.current.spaceKey.wasPressedThisFrame){rb.AddForce(Vector3.up*5,ForceMode.Impulse);}}看到区别了吗Input.GetKeyDown(KeyCode.Space)→Keyboard.current.spaceKey.wasPressedThisFrame更长但每一部分都是类型安全的Keyboard.current是当前键盘设备.spaceKey是空格键控件.wasPressedThisFrame是本帧是否按下。IDE会给你完美的自动补全编译器会检查拼写错误。这是新系统最贴地的用法——直接读取设备状态。其他常用写法// 键盘Keyboard.current.aKey.isPressed// A键是否按住Keyboard.current.wKey.wasReleasedThisFrame// W键本帧是否松开// 鼠标Mouse.current.leftButton.wasPressedThisFrame// 左键本帧是否按下Mouse.current.position.ReadValue()// 鼠标位置Vector2Mouse.current.scroll.ReadValue()// 滚轮增量Vector2// 手柄Gamepad.current.buttonSouth.wasPressedThisFrame// A/×键Gamepad.current.leftStick.ReadValue()// 左摇杆Vector2Gamepad.current.rightTrigger.ReadValue()// 右扳机float如果你只是想快速上手写到这里就已经够用了。但新系统的真正威力在于下面要讲的Action系统。第三步理解Action的核心思想Action动作是新系统的灵魂。要理解它先看一个痛点假设你在角色控制脚本里写了if(Keyboard.current.spaceKey.wasPressedThisFrame)Jump();现在需求变了玩家想用手柄A键跳跃 → 你要改代码加一个判断玩家想自定义按键 → 你要写一整套映射管理手机版要用屏幕按钮跳跃 → 你又要加一个分支代码里写死了按什么键就意味着以后每次改按键都要改代码。Action的思想是代码不关心按了什么只关心想做什么。// 代码只声明我关心一个叫Jump的动作jumpAction.performedctxJump();至于Jump到底对应空格键、手柄A键、还是屏幕按钮——那是配置的事不是代码的事。这就是从面向按键到面向意图的转变。第四步创建你的第一个InputActionAsset现在我们来实际操作。1. 创建资产在Project窗口右键 →Create Input Actions命名为PlayerControls。2. 双击打开编辑器你会看到一个三列布局左列Action Maps动作图中列Actions动作右列Properties属性3. 创建Action Map点击左列的命名为Gameplay表示游戏玩法阶段的输入配置。4. 创建Action在中列点创建一个叫Jump的Action。5. 添加Binding绑定展开Jump看到一个No Binding。点它右边Properties里点Path旁边的按钮选择Keyboard Space。再点Jump右侧的选Add Binding再绑定到Gamepad Button South这样A键和手柄A键都能触发跳跃。6. 保存点击左上角的Save Asset。现在你有了一个叫Jump的动作它同时绑定到键盘空格键和手柄A键。注意你的代码里还没有出现任何空格键或A键的字样——绑定完全在资产里。第五步在代码里使用Action有了资产怎么用呢有三种典型方式从简单到强大方式一直接引用资产最简单在角色脚本里usingUnityEngine;usingUnityEngine.InputSystem;publicclassPlayerController:MonoBehaviour{publicInputActionAssetcontrols;// 拖入PlayerControls资产privateInputActionjumpAction;voidOnEnable(){// 找到Gameplay Action Map里的Jump动作jumpActioncontrols.FindActionMap(Gameplay).FindAction(Jump);jumpAction.performedOnJump;// 订阅事件jumpAction.Enable();// 启用动作}voidOnDisable(){jumpAction.performed-OnJump;jumpAction.Disable();}voidOnJump(InputAction.CallbackContextctx){Debug.Log(跳跃);// 执行跳跃逻辑}}关键点OnEnable里订阅事件OnDisable里取消订阅——避免脚本销毁后回调还在跑Enable()必须调用否则Action不会触发InputAction.CallbackContext包含了这次触发的详细信息触发时间、输入值等方式二使用PlayerInput组件最推荐这是Unity官方最推荐的方式让新手也能快速上手1. 给你的角色GameObject挂上PlayerInput组件在AddComponent里搜索2. 在PlayerInput组件里配置Actions拖入PlayerControls资产Default Map选GameplayBehavior选Invoke Unity Events新手最友好的模式3. 展开Events找到你的Action比如Jump点添加回调绑定到脚本的方法publicclassPlayerController:MonoBehaviour{// 在Inspector里把这个方法拖进Jump事件publicvoidOnJump(InputAction.CallbackContextctx){if(ctx.performed){Debug.Log(跳跃);}}}这种方式的好处是回调完全在Inspector里配置代码里连Action的名字都不用出现。策划改按键、程序不需要动代码。方式三生成C#类最优雅在InputActionAsset的Inspector里勾选Generate C# ClassUnity会自动生成一个和你的资产对应的C#类usingUnityEngine;publicclassPlayerController:MonoBehaviour{privatePlayerControlscontrols;// 自动生成的类voidAwake(){controlsnewPlayerControls();controls.Gameplay.Jump.performedctxJump();}voidOnEnable()controls.Gameplay.Enable();voidOnDisable()controls.Gameplay.Disable();voidJump(){Debug.Log(跳跃);}}看那句controls.Gameplay.Jump.performed——完全类型安全IDE有完整的自动补全重构工具能安全重命名。这才是新系统的完全体。第六步那个让人困惑的CallbackContext每个Action回调都有一个InputAction.CallbackContext ctx参数。它到底是什么voidOnJump(InputAction.CallbackContextctx){ctx.phase// 当前阶段Started / Performed / Canceledctx.performed// 是不是Performed阶段ctx.started// 是不是Started阶段ctx.canceled// 是不是Canceled阶段ctx.ReadValuefloat()// 读取输入值比如扳机压力ctx.ReadValueVector2()// 读取二维输入比如摇杆ctx.control// 触发的具体控件比如space keyctx.time// 触发时间戳ctx.duration// 已按住的时长}为什么要有started、performed、canceled三个阶段想象一个长按0.5秒开火的技能Started玩家刚按下按键的瞬间0秒时Performed按住满0.5秒技能触发0.5秒时Canceled玩家松开或不满足条件比如提前松开对于普通的按一下跳跃三个阶段几乎同时触发你只需要在performed里处理。但对于长按、连击、蓄力等复杂输入这三个阶段就至关重要了。第七步读取移动输入的正确姿势WASD控制移动是最常见的需求。看看新系统怎么优雅地做到1. 在资产里创建Move ActionAction Type选ValueControl Type选Vector22. 添加Binding时选Add 2D Vector Composite会自动展开成四个子绑定Move (Vector2) ├── Up: Keyboard/w ├── Down: Keyboard/s ├── Left: Keyboard/a └── Right: Keyboard/d3. 代码里读取publicvoidOnMove(InputAction.CallbackContextctx){Vector2dirctx.ReadValueVector2();// dir.x 是水平方向 (-1到1)// dir.y 是垂直方向 (-1到1)}或者在Update里持续读取voidUpdate(){Vector2dirmoveAction.ReadValueVector2();transform.Translate(newVector3(dir.x,0,dir.y)*speed*Time.deltaTime);}这就是Composite的威力——把四个按键编织成一个二维向量代码里拿到的就是清爽的Vector2。第八步Interaction让复杂输入变简单新系统内置了多种交互模式一个最实用的例子长按蓄力。1. 在资产里选中你的Fire Action的Binding2. 在右边Properties里找到Interactions点选Hold3. 设置Hold Time 0.54. 代码里publicvoidOnFire(InputAction.CallbackContextctx){if(ctx.started)Debug.Log(开始蓄力);if(ctx.performed)Debug.Log(蓄力完成发射);if(ctx.canceled)Debug.Log(取消或释放);}不需要写任何计时器代码Interaction帮你处理了所有时序逻辑。想改成双击换成MultiTap就行。想改成慢速按下换成SlowTap。第九步Action Type到底选哪个创建Action时你会面对三个选项Value读取当前值适合摇杆、扳机、鼠标位置这种持续变化的输入。会自动应用Disambiguation多设备优先级。Button按钮式输入适合跳跃、开火这种离散触发。当值超过阈值就触发performed。Pass Through不做任何过滤所有输入变化都通过。适合特殊需求比如同时监听多个设备。记忆口诀读值用Value按键用Button除非特殊需求别碰Pass Through。尾声从看不懂到用得爽现在让我们回顾一下你已经掌握的核心概念Device物理输入设备Keyboard.current这种Action逻辑动作Jump、Move、FireBinding动作到具体按键的绑定Action Map一组Action的集合Gameplay / UIComposite把多个按键组合成一个复合输入WASD → Vector2Interaction交互模式Hold、Tap、MultiTapCallbackContext回调事件的详细信息phase、value、time以及三种使用方式直接查设备Keyboard.current.spaceKey.wasPressedThisFrame—— 快速简单PlayerInput组件在Inspector里配置回调 —— 新手友好生成C#类类型安全的强大写法 —— 大型项目首选看不懂新输入系统是因为它引入了一层抽象——从物理按键到逻辑意图的抽象。一旦你翻过这堵墙你会发现它带来的灵活性和扩展性是旧系统望尘莫及的。现在打开Unity创建一个InputActions资产动手试一试吧。十分钟的实践胜过一小时的阅读。当你亲手让空格键和手柄A键同时触发跳跃时那种啊原来是这样的顿悟感会让所有这些概念在你脑海里瞬间连成一片。祝你玩得开心。