前言
官方教程
注意
新的输入系统需要 Unity 2019.4+ 和 .NET 4 运行时。它不适用于 .NET 3.5 的项目。
教程版本:Unity 2021.3.26
1. 安装
1.1 打开 Package Manager
导航栏 -> Window -> Package Manager
![![[Pasted image 20240325155507.png]]](https://img-blog.csdnimg.cn/direct/768932385f0946d08ca43e21637502b4.png)
1.2 安装 Input System
选择 Unity Registry 在列表中找到 Input System 点击Install安装
![![[Pasted image 20240325155721.png]]](https://img-blog.csdnimg.cn/direct/9e0ab160d6e94dbe8134477cd51b8ac3.png)
点击 Yes 启用新版 Input System 等待Unity重新启动
![![[Pasted image 20240325161420.png]]](https://img-blog.csdnimg.cn/direct/9e27fc6faeaa4e79947f4d17a143a9d2.png)
Unity 默认会同时启用旧版和新版输入系统,你可以在 Player settings 中(Edit -> Project Settings -> Player ->Active Input Handling 找到相应的设置。可以随时修改这里的设置,这样做依然会重启编辑器。
![![[Pasted image 20240325162301.png]]](https://img-blog.csdnimg.cn/direct/d685f9d17afc4699b503c5774ee613f1.png)
2. 入门指南
2.1 快速监听某个按键按下抬起操作
void Update()  
{  
    // 检查空格键是否在这个帧被按下  
    if (Keyboard.current.spaceKey.wasPressedThisFrame)  
    {        
	    Debug.Log("Space key was pressed");  
    }   
    // 检查空格键是否在这个帧被释放  
    if (Keyboard.current.spaceKey.wasReleasedThisFrame)  
    {        
	    Debug.Log("Space key was released");  
    }   
    // 检查左鼠标键是否在这个帧被按下  
    if (Mouse.current.leftButton.wasPressedThisFrame)  
    {        
	    Debug.Log("Left mouse button was pressed");  
    }  
    // 检查左鼠标键是否在这个帧被释放  
    if (Mouse.current.leftButton.wasReleasedThisFrame)  
    {        
	    Debug.Log("Left mouse button was released");  
    }
}
2.2 使用可视化编辑器来建立映射
Project -> Create -> Input Actions
![![[Pasted image 20240325165116.png]]](https://img-blog.csdnimg.cn/direct/0ffa5a4c704c43d1a726afc2b9f6115e.png)
新建 Input Actions 给其命名(名称无所谓),笔者命名为 Test Input Controls 完成后,选中该文件勾选 Generate C# Class点击 Apply 后 Unity 会为我们生成一个 Action 的包装类,方便后续在代码中引用。
![![[Pasted image 20240325173907.png]]](https://img-blog.csdnimg.cn/direct/80d4dfca24824a209cb0129af2f1480f.png)
Action Map
可以理解为一个组织和管理输入动作的一种方式。通过将相关的输入动作放在同一个Action Map中,可以更好地管理输入逻辑。例如,可以将所有与玩家移动相关的输入动作放在一个叫做"Movement"的Action Map中。
Action
一个具体的输入动作,比如按键按下、摇杆移动等。
生成结束点击 Edit asset 创建第一个 Action Map 并将其命名为 Player 并将 Actions 列表生成的 Action 重命名为 Fire 。
![![[Pasted image 20240325181359.png]]](https://img-blog.csdnimg.cn/direct/272e49eb2d7040fbb4d79d8b2c941a82.png)
选中 < No Binding > 给 Fire Action 映射对应的按键(按键可以自定义,笔者映射的按键为键盘的 K 键)
![![[Pasted image 20240325181748.png]]](https://img-blog.csdnimg.cn/direct/89b3ce33113442c491f8255fad911c18.png)
也可以绑定多个按键对应不同的操作设备,笔者映射的第二个按键为鼠标左键
![![[Pasted image 20240326094550.png]]](https://img-blog.csdnimg.cn/direct/2b3c2e31742048f88faae401a48f5080.png)
![![[Pasted image 20240326180304.png]]](https://img-blog.csdnimg.cn/direct/088362eb03a545cdacd8098e537d6289.png)
 完成上述操作后点击 Save Asset 保存当前映射表,这样做可以绑定多个物理输入得到的输入值也只会影响同引用的 Action 对象。
![![[Pasted image 20240326180326.png]]](https://img-blog.csdnimg.cn/direct/27ebe4ce71fa424fb5ec1010f372ea79.png)
2.3 通过代码监听映射表中的按键
创建测试脚本 TestInputSystem (命名可随意),我们需要使用之前的 TestInputControls ,通过监听 started 和 canceled 实现按键按下抬起操作。具体可参考下述代码
// 输入控制类的实例  
private TestInputControls InputControls;  
  
void OnEnable()  
{  
    InputControls = new TestInputControls(); // 创建输入控制实例  
    InputControls.Player.Fire.started += OnFireDown; // 注册开火开始动作的回调  
    InputControls.Player.Fire.canceled += OnFireUp; // 注册开火结束动作的回调  
    InputControls.Enable(); // 启用输入控制  
}  
  
//当开火动作被触发时调用此方法。  
private void OnFireDown(InputAction.CallbackContext Obj)  
{  
    Debug.Log($"Fire Down | KeyName:{Obj.control.name}"); // 输出"Fire Down"到控制台 
}
  
//当开火动作释放时调用此方法。  
private void OnFireUp(InputAction.CallbackContext Obj)  
{  
    Debug.Log($"Fire Up | KeyName:{Obj.control.name}"); // 输出"Fire Up"到控制台 
}
  
//主要用于移除输入动作的回调函数,并禁用输入控制。  
private void OnDisable()  
{  
    InputControls.Player.Fire.started -= OnFireDown; // 移除开火开始事件的监听器  
    InputControls.Player.Fire.canceled -= OnFireUp; // 移除开火结束事件的监听器  
    InputControls.Disable(); // 禁用输入控制  
}
测试效果
可以看到,我们使用一套代码就可以同时监听键盘和鼠标的输入
![![[Pasted image 20240326181829.png]]](https://img-blog.csdnimg.cn/direct/8b49d14e1b2e4271ab665ec3c0966e25.png)
按下抬起有了,要想实现长按也很简单。选中 TestInputControls 点击 Edit asset
 在 Action Properties 一栏点击 Interactions 后方的+号添加 Hold
Hold:按下并按住至少设定的持续时间(默认为defaultHoldTime),则执行动作。(长按执行操作)
MultiTap:需要多次轻击(在tapTime内按下并释放),每次轻击之间的间隔不超过tapDelay秒(双击或多击)
Press:根据按钮的按下和释放顺序来触发特定的操作(例如:在按下按钮后执行某个动作或在释放按钮时执行某个操作)
SlowTap:按下并按住控件一段时间后释放时执行操作(长按释放后执行操作)
Tap:按下并按住小段时间内释放执行操作(点击)
![![[Pasted image 20240326140155.png]]](https://img-blog.csdnimg.cn/direct/90a9f61ac38948778639e660edac03e1.png)
添加完 Hold 后,我们看一下它的两个变量。如何默认值不能满足你的需求,取消勾选 Default 可自定义变量值。修改 Hold Time 变量一般即可满足需求
Press Point:按下按键这个阈值才能被认为是按下(笔者理解的是按压力度)
Hold Time:按下并按住按键保持的时间(以秒为单位)。
![![[Pasted image 20240326142645.png]]](https://img-blog.csdnimg.cn/direct/cd7b3491b6074bb79611afd6cfb5912f.png)
还是之前的代码在此基础上增加了长按监听的代码,具体参考下述代码
// 输入控制类的实例  
private TestInputControls InputControls;  
  
void OnEnable()  
{  
    InputControls = new TestInputControls(); // 创建输入控制实例  
    InputControls.Player.Fire.started += OnFireDown; // 注册开火开始动作的回调  
    InputControls.Player.Fire.performed  += OnLongPress; // 注册长按动作的回调  
    InputControls.Player.Fire.canceled += OnFireUp; // 注册开火结束动作的回调  
    InputControls.Enable(); // 启用输入控制  
}  
  
//当开火动作被触发时调用此方法。  
private void OnFireDown(InputAction.CallbackContext Obj)  
{  
    Debug.Log($"Fire Down | KeyName:{Obj.control.name}"); // 输出"Fire Down"到控制台 
}  
  
//当开火动作持续时调用的方法。  
private void OnLongPress(InputAction.CallbackContext Obj)  
{  
    Debug.Log($"Fire Long Press | KeyName:{Obj.control.name},持续时间{Obj.duration}"); // 输出动作持续时间  
}  
  
//当开火动作释放时调用此方法。  
private void OnFireUp(InputAction.CallbackContext Obj)  
{  
    Debug.Log($"Fire Up | KeyName:{Obj.control.name}"); // 输出"Fire Up"到控制台  
}  
  
//主要用于移除输入动作的回调函数,并禁用输入控制。  
private void OnDisable()  
{  
    InputControls.Player.Fire.started -= OnFireDown; // 移除开火开始事件的监听器  
    InputControls.Player.Fire.performed  -= OnLongPress; // 移除长按事件的监听器  
    InputControls.Player.Fire.canceled -= OnFireUp; // 移除开火结束事件的监听器  
    InputControls.Disable(); // 禁用输入控制  
}
经过上述步骤,我们学习到了新版 InputSystem 中的三个最基本的按键触发。



















