文章目录
- 一、前言
- 二、新旧版的键盘按键监听对比
- 三、安装
- 四、新旧输入系统切换
- 五、使用可视化编辑器来建立Input System映射
- 六、通过代码监听映射表中的按键
- 七、Input Debug
- 八、重新绑定控制按键
- 九、移动端支持
- 区分不同设备的配置表(2024/07/02补充)
- UI交互
- 常见的输入绑定
- 结合Player Input控制输入(2024/07/23补充)
- 全局配置Default Deadzone Min死区(2024/08/28补充)
- 监听按钮按下和抬起,并获取按键的长按时间
- 通过接口的方式监听按钮(2024/10/15补充)
- 参考
- 完结
注意: 新的输入法系统需要 Unity 2019.4+ 和 .NET 4 运行时。它不适用于 .NET 3.5 的项目。
一、前言
在游戏开发中,良好的输入系统是确保游戏玩家与游戏世界交互流畅的关键之一。长期以来,Unity 的老版输入系统 InputManager 在处理输入方面发挥了重要作用。然而,随着游戏开发技术的不断发展和用户需求的日益增加,Unity 推出了一种全新的输入系统:Input System。
Unity 的 Input System 是 Unity 提供的一种新的输入系统,相较于旧版的 InputManager,它具有以下优点:
-
灵活性和可配置性: Input System 提供了更灵活和可配置的输入管理方案。你可以通过代码或者通过可视化工具来配置输入,而不是像旧版的 InputManager 那样需要在编辑器中手动添加和管理输入。
-
跨平台支持: Input System 提供了更好的跨平台支持,可以在不同平台上统一处理输入,减少了针对不同平台的输入处理代码的编写。
-
输入处理性能优化: Input System 的设计更加高效,能够更好地管理输入事件的处理,降低了输入处理的性能开销,特别是在大量输入事件的情况下。
-
多种输入设备支持: Input System 对多种输入设备(如键盘、鼠标、手柄、触摸屏等)提供了更好的支持,可以更方便地处理不同输入设备的输入。
-
可扩展性: Input System 的设计更加模块化和可扩展,可以方便地扩展新的输入设备或者自定义输入处理逻辑,满足不同项目的需求。
总的来说,Input System 是 Unity 提供的一种更先进、更灵活、更高效的输入管理方案,能够帮助开发者更方便地处理输入,并提升游戏的性能和跨平台兼容性。
二、新旧版的键盘按键监听对比
1、以监听"A"键按下,抬起,按住为例
- 旧版:
Input.GetKeyDown(KeyCode.A);
Input.GetKeyUp(KeyCode.A);
Input.GetKey(KeyCode.A);
- 新版:
Keyboard.current.aKey.wasPressedThisFrame;
Keyboard.current.anyKey.wasReleasedThisFrame;
Keyboard.current.anyKey.isPressed;
2、新旧版的鼠标左键监听对比:
- 旧版:
Input.GetMouseButtonDown(0);
Input.GetMouseButtonUp(0);
Input.GetMouseButton(0);
- 新版:
Mouse.current.leftButton.wasPressedThisFrame;
Mouse.current.leftButton.wasReleasedThisFrame;
Mouse.current.leftButton.isPressed;
3、鼠标位置和滚轮的数据获取
- 鼠标位置对比
旧版:Input.mousePosition;
新版:Mouse.current.position;
- 滚轮对比
旧版: Input.GetAxis("Mouse ScrollWheel");
新版:Mouse.current.scroll.ReadValue();
三、安装
导航栏 -> Window -> Package Manager,选择 Unity Registry 在列表中找到 Input System 点击 Install 安装
四、新旧输入系统切换
Unity 默认会同时启用旧版和新版输入系统,你可以在 Player settings 中(Edit -> Project Settings -> Player ->Active Input Handling) 找到相应的设置。可以随时修改这里的设置,这样做依然会重启编辑器。
五、使用可视化编辑器来建立Input System映射
Project -> Create -> Input Actions
1、Action Map:行为映射表
一个Input Actions可以有多个Map。每个Map下面又有许多Action,可以批量控制Action启用与禁用。比如有一个UI Map,他包含选项的上,下,左,右,确定等功能,我们将这些功能绑定在方向键。另一个Car Map,他控制赛车的移动,绑定的同样是方向键。为了避免功能冲突,我们可以再拉起UI面板的时候,整体禁用Car Map,关闭UI面的时候禁用UI Map,启用Car Map。以及其他类似的操作。
切换不同的输入系统
游戏时候可以用gameplay系统
而退出游戏时我们可以用UI输入系统
就比如我们进游戏选择菜单的时候用UI系统
我们玩游戏的时候就用gameplay系统
代码切换不同输入系统
# 切换操作映射
public void SwitchActionMap(InputActionMap actionMap)
{
parameter.inputSystem.Disable(); // 禁用当前的输入映射
actionMap.Enable(); // 启用新的输入映射
}
# 调用
SwitchActionMap(parameter.inputSystem.Player); // 切换到游戏操作的输入映射
SwitchActionMap(parameter.inputSystem.UI);//切换为UI输入
2、Action:输入行为资产
一个具体的输入动作,比如按键按下、摇杆移动等。可以理解成自定义的输入行为(动作)的集合。一个输入动作可以由一种或者多种输入信号组成。比如“前进”这个动作,可以被“W”键触发,也可以被“↑”方向键触发,甚至可以被手柄的“↑”键触发。
生成结束点击 Edit asset 创建第一个 Action Map 并将其命名为 Player 并将 Actions 列表生成的 Action 重命名为 Fire 。
也可以绑定多个按键对应不同的操作设备,我这里映射的第二个按键为鼠标左键
3、Action Properties:操作属性
3.1、Action Type:动作类型
动作可分为三种类型
Value
(值):这是用来处理可以变化的数值,比如手柄上的摇杆。它可以返回连续的数值,范围内的任意值都可以,比如从-1到1。这类动作适用于需要获取和处理变化的数字数据的场景。
Button
(按钮):这种类型的动作很简单,只关心按钮是否被按下。它通常返回两个值:按下(1)或抬起(0)。适用于处理单一的按钮事件。
Pass Through
(透传):这种类型的动作是用来将输入直接传递给另一个地方,不对其进行处理。它用于持续变化的输入数据,比如滑块的实时值。
3.2、Control Type:设置按键返回值的类型
下面是对这些控制类型的简要解释:
-
Any(任意):
- 定义:表示控制器返回任何类型的数据。
- 用途:用于处理不确定类型的数据,可以根据实际情况解析为其他具体类型。
-
Analog(模拟):
- 定义:通常用于表示一个范围内的连续数值。
- 用途:适合处理模拟输入设备的数据,如摇杆或滑块,通常返回一个浮点数。
-
Axis(轴):
- 定义:表示一个连续的数值范围,通常用于表示方向或力度。
- 用途:适合于需要表示方向或位置的输入设备,如游戏手柄的摇杆。
-
Bone(骨骼):
- 定义:用于表示骨骼动画系统中的骨骼数据。
- 用途:常用于角色动画中,表示骨骼的状态或位置。
-
Delta(增量):
- 定义:表示与前一个帧相比的变化量。
- 用途:用于处理需要跟踪增量变化的输入数据,如鼠标的移动量。
-
Digital(数字):
- 定义:表示离散的状态,通常是0和1。
- 用途:用于处理简单的开关状态,比如按钮按下或释放的状态。
-
Double(双精度浮点数):
- 定义:表示一个双精度浮点数,精度比普通浮点数更高。
- 用途:用于需要高精度数值的输入数据,如精确的位置或速度数据。
-
Dpad(方向键):
- 定义:表示方向键的状态,通常为一个离散的方向(上、下、左、右)。
- 用途:用于处理方向控制输入,如游戏手柄上的方向键。
-
Eyes(眼睛):
- 定义:表示眼睛位置或方向的数据。
- 用途:用于眼动追踪或虚拟现实中的眼睛跟踪。
-
Integer(整数):
- 定义:表示一个整数值。
- 用途:用于处理离散的、可计数的输入数据,比如选择的选项编号。
-
Pose(姿势):
- 定义:表示对象的姿态或位置。
- 用途:常用于虚拟现实或增强现实中,表示用户或物体的姿态数据。
-
Quaternion(四元数):
- 定义:用于表示旋转的四元数数据。
- 用途:常用于3D空间中的物体旋转,避免了欧拉角的万向节死锁问题。
-
Stick(摇杆):
- 定义:表示摇杆的输入数据,通常为二维或三维向量。
- 用途:用于获取摇杆的位移数据,可以表示方向和力度。
-
Touch(触摸):
- 定义:表示触摸输入的数据。
- 用途:用于处理触摸屏或触摸板上的输入,通常包括触摸点的位置和压力。
-
Vector2(二维向量):
- 定义:表示一个二维坐标的向量。
- 用途:用于处理需要两个维度数据的输入,例如2D游戏中的位置或方向。
-
Vector3(三维向量):
- 定义:表示一个三维坐标的向量。
- 用途:用于处理需要三个维度数据的输入,例如3D空间中的位置或方向。
3.3、Initial State Check:初始状态检查
启用 Action时,Action绑定的Control可能已经具有非默认状态,系统依次检查所有被绑定到此Action的Control,并立即响应处于非默认状态下的控件。
补充:输入系统将不同种类的输入抽象为Control。Control表示输入值的来源,例如,某个float值来源于键盘上的某个按键,某个Vector2值来源于鼠标单帧的位移,某个Vector2值来源于手柄上的摇杆。
3.4、Interactions:交互方式, 点击,长按,双击等
所有的方式都会默认有三个事件Started、Performed、Canceled。举一个明显的例子,长按(手指按住1秒以上认为是长按):在按下去的瞬间触发Started,在任意时间松开触发Canceled,如果连续按压时间达到1秒触发Performed。
Hold:长按
需要保持按压一段时间才算完成这个动作。就像上方举得例子。
添加完 Hold 后,看一下它的两个变量。如果默认值不能满足你的需求,取消勾选 Default 可自定义变量值。修改 Hold Time 变量一般即可满足需求
Press Point
:表示一个临界点,只有过了这个值才算按下。如果Button则只有0和1。如果是摇杆类的按钮,则需要推动幅度大于PressPoint才行。
Hold Time
:长按时间,按下时间达到Hold Time后会立刻触发Performed。
Default
如果勾选则会采用Unity提供的默认值,如果想要自定时间和临界值,请取消勾选。
Open Input Settings
:默认值可以点击Open Input Settings进行查看并修改,也可以“Edit→Project Settings→Input System Package”打开查看并修改。这两项后续不再讲述。
Multi Tap:连击,在规定时间间隔内点击指定的次数。
Tap Count:连击次数。
Max Tap Spacing:两次点击之间的时间间隔。
Max Tap Duration:单次点击 按下与抬起之间的最大持续时间。
只有每次点击都满足上述两个条件,才会触发Performed。
Press:类似按钮,
Press Only:在按下的时候触发Started和 Performed,在抬起的时候触发Canceled。
Release Only:在按下的时候Started,在抬起的时候触发Canceled和Performed。
Press And Release:在按下的时候触发Started和 Performed,抬起的时候触发Canceled和Performed。
Slow Tap:缓慢点击
他与Hold的区别是,在达到最短按压时间后不会立刻触发Performed,而是在松开的瞬间触发Performed。
Min Tap Duration按压的最短时间。
Tap:单击
可以看做只点击一次的Multi Tap。选项在Multi Tap中也有讲述
3.5、Processors:输入值处理
对返回的Value作出指定处理,如取反,限定范围等等。这个地方会因为上边选择的Control Type不同从而导致出现的选项也不同。部分功能类似的选项就会合并讲解。
Clamp:将输入值限制在[min,max]之间,值类型为Float。
Invert:将输入值取反(乘以-1)。应用场景,如果某方向控制键,左输入1右输入-1,我们日常的坐标系都是左为负数,右为正数,为了符合习惯可以取反。
Invert Vector2:同上。可以单独选择取反哪个轴。
Invert Vector3:同上。略。
Normalize:如果最小值>=0,则将[min,max]范围内的输入值规格化为无符号规格化形式[0,1],如果最小值<0,则将输入值规格化为有符号规格化形式[-1,1]。
Normalize Vector2:将输入值归一化,模长为1。比如使用摇杆控制人物移动时,我们往右前方移动,如果值为(1,1)那么就会比单纯前进(1,0)速度要快。这不是我们想要的,所以就要将输入值的模长限制为1。设置后可能会返回(0.71,0.71)其他角度类似。
Normalize Vector3:同上。
Scale:输入值乘以Factor
Scale Vector2:将X轴与x相乘,Y轴与y相乘。
Scale Vector3:类似同上。
Stick Deadzone:摇杆死区处理。摇杆或者其他设备可能存在轻微误触或者其他原因造成的信号问题,在边缘地区不准确。比如将摇杆右滑到底切换下一页,因为某些原因输入值永远在0.99f等等情况。所以只要小于Min值的信号都将变为0,大于Max值的信号都将变为1。
Axis Deadzone:axis死区处理。绝对值小于最小值的任何值为 0,绝对值大于最大值的任何值为 1 或 -1。
4、Binding Properties:结合特性
4.1、Binding
选中当前未绑定的,在右侧面板会有Binding、Interactions、Processors三个选项。
其中Interactions和Processor是针对当前Binding的特别设置,与Action功能一致。如果此处未进行设置,就使用上级的Interactions/Processor设置;如果进行了设置,以此处Interactions/Processor的设置为准。
Binding是此处的核心,它的作用是用来对输入信号进行绑定。输入系统将Action与Control之间的连接抽象为Binding。Binding包含一条指向Control的控件路径,多个Binding可以指向同一个Control,一个Action可包含多个Binding。系统收到某个控件输入的数据时,会驱动所有绑定了该控件的Action进行响应。
path
选中 < No Binding > 给 Fire Action 映射对应的按键(按键可以自定义,比如这里映射的按键为鼠标左键)
4.2、Composite 用于组合多个输入绑定的方法
添加
Composite Type
2D Vector
:复合输入用于将两个输入轴(例如水平和垂直轴)组合成一个 Vector2。这是常用的输入类型,例如用来处理方向控制。它通常用于需要二维方向输入的场景,比如控制角色移动或视角。
One Modifier
:复合输入允许你将一个主要输入与一个修饰输入组合起来。修饰输入会影响主要输入的行为。例如,你可以用它来实现一个动作需要按住某个修饰键的功能。比如实现按住鼠标右键再移动才能控制相机视野旋转功能
Two Modifiers
:跟前面类似,不过可以多加1个绑定,用于需要两个修饰键来影响主要输入的场景。
1D Axis
:复合输入用于处理单一轴的输入,通常是 Single 类型的值。它可以用于简单的轴输入,例如游戏中的一个方向键。
Button With One Modifier
:复合输入用于将一个主要按钮输入与一个修饰按钮组合起来。这个复合输入需要两个按钮的状态:一个主按钮和一个修饰按钮。用法:用于需要组合两个按钮输入的场景,例如在按下某个按钮的同时按下另一个按钮以触发特殊动作。
Button With Two Modifiers
:复合输入类似于 Button With One Modifier,但需要两个修饰按钮配合一个主要按钮。这意味着你需要同时按下三个按钮(一个主要按钮和两个修饰按钮)来触发动作。用法:用于需要同时按下三个按钮的复杂场景,例如执行复杂的操作或技能组合。
Mode 如何处理输入数据
将输入视为数字控制还是模拟控制。
Analog
: 处理模拟输入信号,如游戏控制器的摇杆或模拟触摸输入。输入值通常是浮点数,范围在 -1 到 1 之间。可以实现按手柄摇杆的力度控制移动速度,类似带加速减速过程的效果。
Digital Normalized
:处理数字输入,但以归一化形式输出。这意味着输入值会被标准化到 -1、0 和 1 之间。它用于处理需要归一化的数字输入,常见于输入映射中的状态表示。
Digital
:处理数字输入信号,如按钮按下或释放。输出值通常是布尔值(按下为 true,未按下为 false),但在一些实现中,输出可以表示为 0 或 1。
5、保存
完成上述操作后点击 Save Asset 保存当前映射表,这样做可以绑定多个物理输入得到的输入值也只会影响同引用的 Action 对象。
六、通过代码监听映射表中的按键
快速创建Input Actions映射
给玩家新增Player Input组件,点击创建新的输入系统,生成之后就可以删除Player Input组件了
会自动给我们创建好一些必备输入参数,比如移动
代码调用,点击自动生成代码
代码控制
创建测试脚本 PlayerInput (命名可随意),我们需要使用之前的 InputActions映射
通过监听 started 和 canceled 实现按键按下抬起操作。具体可参考下述代码
using UnityEngine;
using UnityEngine.InputSystem;
/// <summary>
/// 玩家输入
/// </summary>
public class PlayerInput : MonoBehaviour
{
public Vector2 MoveInput {
get; private set; }// 用于存储移动输入的向量
public Vector2 LookInput {
get; private set; }// 用于存储视角输入的向量
public bool RunIsPressed {
get; private set; }
public bool JumpIsPressed {
get; private set; }
private InputActions _input;
private void OnEnable()
{
_input = new InputActions();
_input.Player.Enable();
_input.Player.Move.performed += SetMove;
_input.Player.Move.canceled += SetMove;
_input.Player.Look.performed += SetLook;
_input.Player.Look.canceled += SetLook;
_input.Player.Run.started += SetRun;
_input.Player.Run.canceled += SetRun;
_input.Player.Jump.started += SetJump;
_input.Player.Jump.canceled += SetJump;
_input.Player.Roller.performed += SetRoller;
_input.Player.Roller.canceled += SetRoller;
}
private void OnDisable()
{
_input.Player.Move.performed -= SetMove;
_input.Player.Move.canceled -= SetMove;
_input.Player.Look.performed -= SetLook;
_input.Player.Look.canceled -= SetLook;
_input.Player.Run.started -= SetRun;
_input.Player.Run.canceled -= SetRun;
_input.Player.Jump.started -= SetJump;
_input.Player.Jump.canceled -= SetJump;
_input.Player.Roller.performed -= SetRoller;
_input.Player.Roller.canceled -= SetRoller;
_input.Player.Disable();
}
private void SetMove(InputAction.CallbackContext context)
{
MoveInput = context.ReadValue<Vector2>();
}
private void SetLook(InputAction.CallbackContext context)
{
LookInput = context.ReadValue<Vector2>();
}
private void SetRun(InputAction.CallbackContext context)
{
RunIsPressed = context.started;
// if (context.started)// 当用户按下键时触发
// {
// ChangeCameraWasPressedThisFrame = true;
// } else if (context.performed) {// 按键持续按下
// float holdDuration = (float)context.duration;
// Debug.Log("按键持续时间: " + holdDuration);
//}else if(context.canceled){// 当用户释放键时触发
// ChangeCameraWasPressedThisFrame = false;
// }
}
private void SetJump(InputAction.CallbackContext context)
{
JumpIsPressed = context.started;
}
private void SetRoller(InputAction.CallbackContext context)
{
Debug.Log(context.ReadValue<float>());
}
}
七、Input Debug
Input Debug窗口是一个非常好用的东西,打开方式:
“Window→Analysis→Input Debugger”
这个窗口中,所有可以被识别的输入设备都会被显示在这。之前我们在绑定输入按钮的时候会不会有这么一个疑惑,我怎么知道这个按钮对应哪个信号。还有每个信号的输入值类型又是什么样子呢?
我们就以我的手柄为例,上图中我已经选中了手柄,双击,打开详细界面。
我们可以看到设备的详细信息。Name就是在Unity InputSystem中对应的名称;DisplayName是我手柄上的文字,B就对应我手柄的B;后边还有信号类型方便我们设置Type。此时按动手柄还能通过value看到实时输入值,并且屏幕下方还会实时打印,方便我们调试。爆赞!
比如我此时正在按B键,掰动摇杆,所有的输入信息都会在面板中展示出来,建议各位自己尝试一下。
八、重新绑定控制按键
九、移动端支持
更好用的虚拟摇杆插件:待续
1、虚拟摇杆
虚拟摇杆input system已经帮我们做好了一个非常好的工具,模拟左侧操作杆,只需要挂载On-Screen Stick脚本即可
运行效果,没错就是这么简单,甚至你都不需要修改代码
2、虚拟按钮
绘制按钮UI
模拟不同的按钮
效果
区分不同设备的配置表(2024/07/02补充)
PC的按键勾选分类
手柄的按键勾选分类
把不同的设备按键绑定区分开
UI交互
InputSystem在UI上的应用
在创建canvas的同时
又创建了一个EventSystem
它原本是老版的输入系统
但是我们升级完InputSystem
新版的输入系统之后,它就会报错
我们把它别级为新版的输入系统
Actions Asset里面
默认给我们创建一个DefaultInputActions,绑定的按键和UI事件是对应的
UI的输入时间我们就用默认的就好了,原来的UI就不需要添加任何东西
常见的输入绑定
1、移动
2、跳跃输入
绑定键盘按钮
绑定手柄,如果有的话
3、鼠标滚轮输入
监听鼠标XY轴滚轮
获取值
inputSystem.Player.Roller.ReadValue<Vector2>();
仅监听鼠标Y轴滚轮
获取值
inputSystem.Player.Roller.ReadValue<float>();
结合Player Input控制输入(2024/07/23补充)
这种办法因为在Update一直监听输入,性能肯定没有前面的好,但是单单是输入影响应该也不大,而且这种获取输入的方式真的很优雅,所以这里还是分享一下,大家酌情选择即可
也可以使用下面的方式获取输入
public class UserInput : MonoBehaviour
{
// Singleton instance
public static UserInput instance;
// 移动输入向量
public Vector2 MoveInput {
get; private set; }
// 跳跃输入标志位
public bool JumpJustPressed {
get; private set; }
public bool JumpBeingHeld {
get; private set; }
public bool JumpReleased {
get; private set; }
// 攻击输入标志位
public bool AttackInput {
get; private set; }
// 冲刺输入标志位
public bool DashInput {
get; private set; }
// 菜单打开/关闭输入标志位
public bool MenuopencloseInput {
get; private set; }
private PlayerInput _playerInput;
private InputAction _moveAction;
private InputAction _jumpAction;
private InputAction _attackAction;
private InputAction _dashAction;
private InputAction _menuopenCloseAction;
private void Awake()
{
// 单例模式实例化
if (instance == null)
{
instance = this;
}
_playerInput = GetComponent<PlayerInput>();
SetupInputActions();
}
private void Update()
{
// 每帧更新输入状态
UpdateInputs();
}
private void SetupInputActions()
{
// 从PlayerInput组件初始化输入动作
_moveAction = _playerInput.actions["Move"];
_jumpAction = _playerInput.actions["Jump"];
_attackAction = _playerInput.actions["Attack"];
_dashAction = _playerInput.actions["Dash"];
_menuopenCloseAction = _playerInput.actions["Menuopenclose"];
}
private void UpdateInputs()
{
// 更新特定的输入数值
MoveInput = _moveAction.ReadValue<Vector2>(); // 读取移动输入值
JumpJustPressed = _jumpAction.WasPressedThisFrame(); // 检测跳跃是否刚按下
JumpBeingHeld = _jumpAction.IsPressed(); // 检测跳跃是否正在按住
JumpReleased = _jumpAction.WasReleasedThisFrame(); // 检测跳跃是否刚释放
AttackInput = _attackAction.WasPressedThisFrame(); // 检测攻击是否刚按下
DashInput = _dashAction.WasPressedThisFrame(); // 检测冲刺是否刚按下
MenuopencloseInput = _menuopenCloseAction.WasPressedThisFrame(); // 检测菜单打开/关闭是否刚按下
}
}
全局配置Default Deadzone Min死区(2024/08/28补充)
“Input System Default Deadzone Min” 通常指的是输入系统中的默认死区最小值。它用于设置输入设备(如游戏控制器)的最小响应阈值,即在这个范围内的微小输入变化不会被系统识别,以避免过于敏感的反应。这有助于提供更平滑的输入体验。跟前面的Stick Deadzone
监听按钮按下和抬起,并获取按键的长按时间
public class NewBehaviourScript : MonoBehaviour
{
private InputSystem _input;
private float _holdStartTime; // 按键开始按下的时间
private void OnEnable()
{
_input = new InputSystem();
_input.Player.Enable();
_input.Player.Fire.started += SetFire;
_input.Player.Fire.canceled += SetFire;
}
private void OnDisable()
{
_input.Player.Fire.started -= SetFire;
_input.Player.Fire.canceled -= SetFire;
_input.Player.Disable();
}
private void SetFire(InputAction.CallbackContext context)
{
if (context.started)
{
// 按键开始按下
_holdStartTime = Time.time; // 记录开始时间
Debug.Log("按键开始: " + _holdStartTime);
}
else if(context.canceled)
{
// 按键松开
float holdDuration = Time.time - _holdStartTime; // 计算持续时间
Debug.Log("按键释放: " + Time.time + ", 持续时间: " + holdDuration);
}
}
}
通过接口的方式监听按钮(2024/10/15补充)
using UnityEngine;
using UnityEngine.InputSystem;
public class NewBehaviourScript : MonoBehaviour, InputSystem.IPlayerActions
{
private InputSystem _input;
private void OnEnable()
{
_input = new InputSystem();
_input.Player.Enable();
_input.Player.SetCallbacks(this);
}
private void OnDisable()
{
_input.Player.Disable();
}
public void OnMove(InputAction.CallbackContext context)
{
//一般只用到后三个
switch (context.phase)
{
case InputActionPhase.Disabled://被禁用
Debug.Log("按键被禁用");
break;
case InputActionPhase.Waiting://处于等待
Debug.Log("按键处于等待");
break;
case InputActionPhase.Started://按键开始按下的那一刻
Debug.Log("按键开始按下" );
break;
case InputActionPhase.Performed://按键持续按下
Debug.Log("按键持续按下" );
break;
case InputActionPhase.Canceled://按键松开
Debug.Log("按键松开");
break;
}
}
public void OnLook(InputAction.CallbackContext context)
{
}
public void OnFire(InputAction.CallbackContext context)
{
}
}
注意
,如果按钮一直按住一个方向,Performed和Started效果其实是一样的,但如果你在持续的移动过程中变换方向,Performed在输入操作期间就会持续触发。这个算一个知识补充,之前没有说过。
参考
【文档】https://docs.unity3d.com/Packages/[email protected]/manual/Actions.html
【文章】https://developer.unity.cn/projects/6602debfedbc2a001dcd1a82
【文章】https://www.bilibili.com/read/cv22947460/
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,以便我第一时间收到反馈,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~