【推荐100个unity插件之18】Unity 新版输入系统Input System的使用,看这篇就够了(2024/10/15补充)

文章目录

注意: 新的输入法系统需要 Unity 2019.4+ 和 .NET 4 运行时。它不适用于 .NET 3.5 的项目。

一、前言

在游戏开发中,良好的输入系统是确保游戏玩家与游戏世界交互流畅的关键之一。长期以来,Unity 的老版输入系统 InputManager 在处理输入方面发挥了重要作用。然而,随着游戏开发技术的不断发展和用户需求的日益增加,Unity 推出了一种全新的输入系统:Input System。

Unity 的 Input System 是 Unity 提供的一种新的输入系统,相较于旧版的 InputManager,它具有以下优点:

  1. 灵活性和可配置性: Input System 提供了更灵活和可配置的输入管理方案。你可以通过代码或者通过可视化工具来配置输入,而不是像旧版的 InputManager 那样需要在编辑器中手动添加和管理输入。

  2. 跨平台支持: Input System 提供了更好的跨平台支持,可以在不同平台上统一处理输入,减少了针对不同平台的输入处理代码的编写。

  3. 输入处理性能优化: Input System 的设计更加高效,能够更好地管理输入事件的处理,降低了输入处理的性能开销,特别是在大量输入事件的情况下。

  4. 多种输入设备支持: Input System 对多种输入设备(如键盘、鼠标、手柄、触摸屏等)提供了更好的支持,可以更方便地处理不同输入设备的输入。

  5. 可扩展性: 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:设置按键返回值的类型

在这里插入图片描述
下面是对这些控制类型的简要解释:

  1. Any(任意)

    • 定义:表示控制器返回任何类型的数据。
    • 用途:用于处理不确定类型的数据,可以根据实际情况解析为其他具体类型。
  2. Analog(模拟)

    • 定义:通常用于表示一个范围内的连续数值。
    • 用途:适合处理模拟输入设备的数据,如摇杆或滑块,通常返回一个浮点数。
  3. Axis(轴)

    • 定义:表示一个连续的数值范围,通常用于表示方向或力度。
    • 用途:适合于需要表示方向或位置的输入设备,如游戏手柄的摇杆。
  4. Bone(骨骼)

    • 定义:用于表示骨骼动画系统中的骨骼数据。
    • 用途:常用于角色动画中,表示骨骼的状态或位置。
  5. Delta(增量)

    • 定义:表示与前一个帧相比的变化量。
    • 用途:用于处理需要跟踪增量变化的输入数据,如鼠标的移动量。
  6. Digital(数字)

    • 定义:表示离散的状态,通常是0和1。
    • 用途:用于处理简单的开关状态,比如按钮按下或释放的状态。
  7. Double(双精度浮点数)

    • 定义:表示一个双精度浮点数,精度比普通浮点数更高。
    • 用途:用于需要高精度数值的输入数据,如精确的位置或速度数据。
  8. Dpad(方向键)

    • 定义:表示方向键的状态,通常为一个离散的方向(上、下、左、右)。
    • 用途:用于处理方向控制输入,如游戏手柄上的方向键。
  9. Eyes(眼睛)

    • 定义:表示眼睛位置或方向的数据。
    • 用途:用于眼动追踪或虚拟现实中的眼睛跟踪。
  10. Integer(整数)

    • 定义:表示一个整数值。
    • 用途:用于处理离散的、可计数的输入数据,比如选择的选项编号。
  11. Pose(姿势)

    • 定义:表示对象的姿态或位置。
    • 用途:常用于虚拟现实或增强现实中,表示用户或物体的姿态数据。
  12. Quaternion(四元数)

    • 定义:用于表示旋转的四元数数据。
    • 用途:常用于3D空间中的物体旋转,避免了欧拉角的万向节死锁问题。
  13. Stick(摇杆)

    • 定义:表示摇杆的输入数据,通常为二维或三维向量。
    • 用途:用于获取摇杆的位移数据,可以表示方向和力度。
  14. Touch(触摸)

    • 定义:表示触摸输入的数据。
    • 用途:用于处理触摸屏或触摸板上的输入,通常包括触摸点的位置和压力。
  15. Vector2(二维向量)

    • 定义:表示一个二维坐标的向量。
    • 用途:用于处理需要两个维度数据的输入,例如2D游戏中的位置或方向。
  16. 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键,掰动摇杆,所有的输入信息都会在面板中展示出来,建议各位自己尝试一下。
在这里插入图片描述

八、重新绑定控制按键

参考:【unity小技巧】新输入系统InputSystem重新绑定控制按键(最全最完美解决方案)

九、移动端支持

更好用的虚拟摇杆插件:待续

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是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_36303853/article/details/138794797