U4S1L7——Input Action类

本章代码关键字

1
2
3
4
5
6
7
8
9
10
11
12
InputAction                    //输入动作类,InputSystem输入监听触发相关的主要内容
inputAction.Enable() //输入监听激活方法
inputAction.started //开始操作时触发的委托
inputAction.performed //真正触发时的委托
inputAction.canceled //结束输入时触发的委托
CallbackContext //输入监听回调信息类,所有作为输入监听方法都需要用这个来作为参数
callbackContext.phase //当前输入状态
callbackContext.action //输入动作行为也就是InputAction对象信息,即触发者传入自己
callbackContext.control //控件信息,传入触发这次监听方法的输入控件名
callbackContext.ReadValue<> //输入值,泛型内填入的类型有输入控件本身决定
callbackContext.duration //输入持续时间
callbackContext.startTime //输入开始时的时间

InputAction

顾名思义,InputAction​ 是 InputSystem​ 帮助我们封装的输入动作类
它的主要作用,是不需要我们通过写代码的形式来处理输入,而是直接在 Inspector窗口 编辑想要处理的输入类型
当输入触发时,我们只需要把精力花在输入触发后的逻辑处理上

我们在想要用于处理输入动作的类中,申明对应的 InputAction​ 类型的成员变量 (注意:需要引用命名空间 UnityEngine.InputSystem
Inspector窗口上就可以进行编辑:

1
2
3
4
5
public class Lesson7 : MonoBehaviour
{
public InputAction move;
public InputAction Fire;
}

Inspector窗口显示内容:image

InputAction参数相关

image

  • 输入设置 —— 齿轮image

    image

    • Action 输入动作设置 - 设置输入的类型,筛选控制的类型

      设置检测哪些输入

      image

      • Action Type:动作类型

        image

        • Value:值类型,主要用于状态连续更改的输入
          例如鼠标的移动,手柄的摇杆。
          如果有多个设备绑定这个Action,
          只会发送其中一个设备(最受控制的)的输入

        • Button:按钮类型,用于每次按下时触发的Action

        • Pass Through:直通类型,和Value一样,
          区别在于如果有多个设备绑定这个Action,会发送所有设备的输入

          例如:当有两个手柄接入到设备时,如果选择值类型,则主手柄输入才会得到值,而直通类型会拿到两个手柄的输入值

      • Control Type:控制类型(该选项在 Action Type 选择 Button 时不会出现)

        在这里选择对应的类型,之后在选择对应设备按键相关属性时,会根据你选择内容的不同,筛选对应内容
        这上面显示的内容就是各设备属性的返回值类型,当你选择他们后,没有选择的类型将不会在之后的按键设置中出现
        很多内容我们基本用不到,相当于是在这里筛选输入设备的返回值

        image

        • Any - 任何值
        • Analog - 模拟值,浮点数
        • Axis - 一维轴浮点数,例如:摇杆输入返回值
        • Bone - 骨骼
        • Digital - 数字
        • Double - 浮点
        • Dpad - 4向按钮,例如:摇杆上的D-pad
        • Eyes - VR相关数值
        • Integer - 整数
        • Quaternion - 四元数
        • Stick - 摇杆相关
        • Touch - 触屏相关
        • Vector2 - 2维向量
        • Vector3 - 3维向量

        例如,在这里选择 Value 和 Vector2:

        QQ_1722922587639

        添加一个手柄输入Binding,这里就只会显示十字键,左摇杆和右摇杆,而其他的按键都没有了

        QQ_1722922687371

        如果在这里选择 Button

        QQ_1722922864354

        添加一个手柄输入Binding,这里就只会显示各种按键了

        QQ_1722922820039

      • Initial State Check:初始状态检查(该选项在 Action Type 选择 Value 时不会出现)

        无论是在启用操作后的下一次输入更新中,如果其任何绑定控件当前处于非默认状态,该操作都应立即触发。
        此检查隐式发生在Value操作上,但可以显式启用Button和Pass Through操作

    • Interactions 相互作用设置 - 处理特殊行为

      用于特殊输入,比如长按、多次点击等等,
      当满足条件时才会触发这个行为(设置长按时间、点击次数等等)

      image

      • 3个委托事件(三个事件在之后的监听输入代码里使用)

        • 开始 started​ - 例如鼠标刚好开始按下的事件
        • 触发 performed​ - 例如鼠标长按一段时间后满足条件触发的事件
        • 结束 canceled​ - 例如鼠标长按未满足条件就松开触发的事件
      • 特殊输入类型及参数

        image

        以下的选项里几乎每个参数都有默认值,可以在InputSystemPackage(特殊输入设置)里修改这些默认值

        • Hold - 适用于需要输入设备保持一段时间的操作

          1. 当按钮按下会触发 started​,

          2. 若在松开按钮前,按住时间大于等于 Hold Time​,
            则会触发 performed(时间一到就触发)

          3. 否则触发 canceled

          4. Press Point:

            在Input System中,每个按钮都有对应的浮点值,
            例如普通的按钮,将会在0(未按下)和1(按下)之间。
            因此我们可以利用这个值(Press Point)来进行区分,
            当大于等于这个值则认为按钮按下了。

          image

        • Tap - 和 Hold 相反,需要在一段时间内按下松开来触发。

          1. 当按钮按下会触发 started​,

          2. 若在Max Tap Duriation时间内(小于)松开按钮,
            触发 performed​,

          3. 否则触发 canceled​。

          4. Press Point:

            在Input System中,每个按钮都有对应的浮点值,
            例如普通的按钮,将会在0(未按下)和1(按下)之间。
            因此我们可以利用这个值(Press Point)来进行区分,
            当大于等于这个值则认为按钮按下了。

          image

        • SlowTap - 保持一段时间操作后松开才触发

          类似 Hold​,
          但是它在按住时间大于等于Max Tap Duriation的时候,
          并不会立刻触发
          performed
          而是会在松开的时候才触发 performed

          image

          Press Point:
          在Input System中,每个按钮都有对应的浮点值,
          例如普通的按钮,将会在0(未按下)和1(按下)之间。
          因此我们可以利用这个值(Press Point)来进行区分,
          当大于等于这个值则认为按钮按下了。

        • MultiTap - 用作于多次点击,例如双击或者三连击。

          • Tap Count为点击次数
            Max Tap Spacing为每次点击之间的间隔
            (默认值为 2 * Max Tap Duration)

          • Max Tap Duration为每次点击的持续时间
            即按下和松开按钮的这段时间

          • 每次点击时间小于Max Tap Duration
            点击间隔时间小于Max Tap Spacing
            点击Tap Count次,触发performed。

          • Press Point:

            在Input System中,每个按钮都有对应的浮点值,
            例如普通的按钮,将会在0(未按下)和1(按下)之间。
            因此我们可以利用这个值(Press Point)来进行区分,
            当大于等于这个值则认为按钮按下了。

          image

        • Press - 可以实现类似按钮的操作

          • Trigger Behavior - 触发行为

            image

            • Press Only:

              按下的时候触发started和performed。
              不触发canceled

            • Release Only:

              按下的时候触发started,
              松开的时候触发performed

            • Press And Release:

              按下的时候触发started和performed,
              松开的时候会再次触发started和performed。
              不触发canceled

          • Press Point:

            在Input System中,每个按钮都有对应的浮点值,
            例如普通的按钮,将会在0(未按下)和1(按下)之间。
            因此我们可以利用这个值(Press Point)来进行区分,
            当大于等于这个值则认为按钮按下了。

          image

    • Processors 值处理加工设置 - 将输入的值进行一次加工

      image

      • Clamp - 将输入值钳制到[min…max]范围

        image

      • Invert - 反转控件中的值(即,将值乘以-1)

      • Invert Vector 2 - 反转控件中的值(即,将值乘以-1)

        image

        • 如果invertX为真,则反转矢量的x轴;
        • 如果invertY为真,则反转矢量的y轴。
      • Invert Vector 3 - 反转控件中的值(即,将值乘以-1)

        image

        • 如果反转x为真,则反转矢量的x轴;
        • 如果反转y为真,则反转y轴;
        • 如果反转z为真,则反转z轴。
      • Normalize - 单位化

        image

        • 如果Min >= Zero,则将[min…max]范围内的输入值规格化为无符号规格化形式[0…1],
        • 如果Min < Zero,则将输入值规格化为有符号规格化形式[-1…1]。
      • Normalize Vector 2 - 将输入向量规格化为单位长度

      • Normalize Vector 3 - 将输入向量规格化为单位长度

      • Scale - 将所有输入值乘以系数

        image

      • Scale Vector 2 - 将所有输入值沿x轴乘以x,沿y轴乘以y

        image

      • Scale Vector 3 - 将所有输入值沿x轴乘以x,沿y轴乘以y,沿z轴乘以z

        image

      • Axis Deadzone - axis死区处理器,缩放控件的值,使绝对值小于最小值的任何值为0,绝对值大于最大值的任何值为1或-1。

        image

        许多控件没有精确的静止点(也就是说,当控件位于中心时,它们并不总是精确报告0),
        换句话来说,有些轴即使我们没有主动的输入,但依然有很小的值在输入进去,这会导致诸如操控的角色在无意间缓慢移动这种问题!
        在死区处理器上使用最小值可避免此类控件的无意输入。
        此外,当轴一直移动时,某些控件不一致地报告其最大值,换句话来说,就是我们即使已经把轴推到最末端,输入进去的值依然不是最大值
        在死区处理器上使用最大值可确保在这种情况下始终获得最大值。

      • Stick Deadzone - 摇杆死区处理器,缩放Vector2控件(如摇杆)的值,
        以便任何幅值小于最小值的输入向量都将得到(0,0),而任何幅值大于最大值的输入向量都将规格化为长度1。

        image

        许多控件没有精确的静止点(也就是说,当控件位于中心时,它们并不总是精确地报告(0,0)),
        换句话来说,有些摇杆即使我们没有主动的去动它,但依然有很小的值在输入进去,这会导致诸如操控的角色在无意间缓慢移动这种问题!
        在死区处理器上使用最小值可避免此类控件的无意输入。
        此外,当轴一直移动时,某些控件不一致地报告其最大值。换句话来说,就是我们即使已经把摇杆推到最末端,输入进去的值依然不是最大值
        在死区处理器上使用最大值可确保在这种情况下始终获得最大值。

  • 点击+号 image 创建输入

    注意

    有些创建输入的选项在特定的情况下不会显示,这取决于你的Input Action 的 Actions - 输入动作设置 是如何设置的
    例如,当 Input Action 在选择 Action Type 选择 Button 时,Add Up\Down\Left\Right Composite 这个创建选项可能就不会显示出来
    你需要设置 Action Type 为 Value,Control Type 为 Vector 2(或者其他符合要求的选项)这个 Add Up\Down\Left\Right Composite 才会显示出来

    image

    在这里创建一个输入后,点击创建出来的 即可设置接受何种输入,
    可以添加多个输入以触发这个成员对应的监听事件,例如跨平台游戏就可以添加不同平台的各种输入
    具体添加监听事件的方法请看这个 ——> InputAction的使用,
    在Inspector窗口设置完成,在脚本里向该 InputAction​ 成员添加监听到输入后执行什么逻辑的监听函数后,即完成输入监听的流程

    • Add Binding
      添加新的输入绑定(单按键输入)

      image

    • Add Positive\Negative Binding(2019版前的名称是:Add 1D Axis Composite)
      添加1D轴组合(类似Input中的水平竖直热键,返回-1~1之间的一个值)

      image

      • Negative:负面按键,例如 0~-1
      • Positive:正向按键,例如 0~1

      image

      • Composite Type:复合类型

      • MinValue:最小值

      • MaxValue:最大值

      • Which Side Wins:哪一方获胜 (即当同时按下时如何处理)

        • Neither:双方没有优先权,返回MinValue和MaxValue的中间值
        • Positive:正面优先,返回maxValue
        • Negative:负面优先,返回minValue
    • Add Up\Down\Left\Right Composite( 2019版前的名称是:Add 2D Vector Composite)
      添加2D向量组合(类似将Input中的水平竖直热键组合在一起,得到的Vector中的x,y分别表示两个轴)

      ​​image​​

      • Up:上 ( 0 , 1 )
      • Down:下 ( 0 , -1 )
      • Left:左 ( -1 , 0 )
      • Right:右 ( 1 , 0 )

      image

      • Composite Type:复合类型

      • Mode:处理模式

        • Analog:模拟值,浮点值
        • Digital Normalized:单位化向量
        • Digital:未单位化的向量
    • Add Up\Down\Left\Right\Forward\Backward Composite
      添加3D向量组合(类似于上面的2D向量组合,多加了一个轴,得到Vector3中的x,y,z分别表示三个轴)

      image

    • Add Button With One Modifier Composite
      添加带有一个复合修改器的按钮(可以理解为双组合键, 比如Ctrl+C、Ctrl+V)

      image

      • Modifier:复合输入内容
      • Binding:输入内容(在2020版及以前,这里的名称是Button)

      举例:复制按键Ctrl+C、Ctrl 为 Modifier、C 为 Binding

    • Add Button With Two Modifier Composite
      添加带有两个复合修改器的按钮(可以理解为三组合键,比如Ctrl+K+U)

      image

      • Modifier:复合输入内容1
      • Modifier:复合输入内容2
      • Button:输入内容

      举例:复制按键Ctrl+K+U,Ctrl为Modifier1,K为Modifier2,U为Binding

  • 创建一种输入后,如何选择要监听什么输入

    点击创建出来的即可设置从哪个控件接受输入

    • Path:从哪个控件接受输入

      • Usages:常用用法
      • GamePad:游戏手柄
      • Joystick:操纵杆
      • Keyboard:键盘
      • Mouse:鼠标
      • Pen:笔
      • Pointer:指针
      • Sensor:传感器
      • TouchScreen:触屏
      • Tracked Device:履带装置
      • XR Controller:XR 控制器
      • XR HMD:XR 头戴显示器
      • Other:其它

    image

InputAction的使用

  1. 启用输入检测

    1
    2
    3
    4
    5
    6
    public InputAction move;

    void Start()
    {
    move.Enable();
    }
    关闭输入检测
    1
    move.Disable();
  2. 操作监听相关

    涉及操作监听的成员变量都是委托,需要向这些委托添加参数为 InputAction.CallbackContext​(是InputAction​的内部结构体)的方法
    触发这些委托方法的输入方式由Inspector窗口内对这些 InputAction​ 的成员的设置决定,具体请看InputAction参数相关

    这里演示的结果是绑定了鼠标左键和键盘A键的效果,也就是说,按下鼠标左键和按下A键都会触发下面的代码

    image

    • 开始操作

      这个开始操作指的是,该 InputAction​ 绑定的输入方法出现输入时触发的委托(即使不满足 Interactions 相互作用设置 里的条件时也会触发)
      inputAction.started​ 是一个事件委托,需要外部添加参数类型为 InputAction.CallbackContext​ 的监听方法,由监听方法来监听开始操作的输入

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      public InputAction move;

      void Start()
      {
      move.Enable();
      move.started += TestFunc;
      }

      private void TestFunc(InputAction.CallbackContext context)
      {
      print("开始操作");
      }

      输出:

      image

    • 真正触发

      这个真正触发指的是,该 InputAction​ 绑定的输入方法出现输入且满足 Interactions 相互作用设置 里的条件时就会触发
      inputAction.performed​ 是一个事件委托,由外部加入参数为 InputAction.CallbackContext​ 的监听方法,由监听方法来监听真正触发的输入

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      public InputAction move;
      public InputAction Fire;

      void Start()
      {
      move.Enable();
      move.performed += (context) =>
      {
      print("触发事件调用");
      };
      }

      输出:

      image

    • 结束操作

      这个结束操作指的是,该 InputAction​ 绑定的输入方法都结束输入时就会触发
      inputAction.canceled​ 是一个事件委托,由外部加入参数为 InputAction.CallbackContext​ 的监听方法,由监听方法来监听结束操作的输入

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      public InputAction move;
      public InputAction Fire;

      void Start()
      {
      move.Enable();
      move.canceled += (context) =>
      {
      print("结束事件调用");
      };
      }

      image

  3. 关键参数 CallbackContext

    该参数为 添加到 InputAction​ 对象的被输入触发的委托的 监听方法所必需的参数

    • 当前状态

      CallbackContext​ 状态的枚举有:

      • 没有启用 Disabled​​
      • 等待 Waiting​​
      • 开始 Started​​
      • 触发 Performed​​
      • 结束 Canceled​​
      1
      2
      3
      4
      5
      6
      move.performed += (callbackContext) =>
      {
      print("触发事件调用");
      //当前状态
      print(callbackContext.phase);
      };

      输出:

      image

    • 动作行为信息

      其实这里的 action​ 就是上面声明的 InputAction​ 成员变量

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      public InputAction move;

      void Start()
      {
      move.Enable();
      move.performed += (callbackContext) =>
      {
      print("触发事件调用");
      //动作行为信息
      print(callbackContext.action.name);
      };
      }

      image

    • 控件信息

      得到输入设备的信息

      1
      2
      3
      4
      5
      6
      move.performed += (context) =>
      {
      print("触发事件调用");
      //控件(设备)信息
      print(callbackContext.control.name);
      };

      按下鼠标左键时:

      image

      按下键盘A键时:

      image

    • 获取值

      注意!这里的泛型使用什么类型取决于你使用的输入方式,例如:摇杆就是****​Vector2​​ ,轴就是****​float​​

      1
      2
      3
      4
      5
      6
      move.performed += (context) =>
      {
      print("触发事件调用");
      //获取值,这里是检测鼠标按键,因此检测值泛型不能用float
      print(callbackContext.ReadValue<float>())
      };
    • 持续时间

      操作持续的时间

      1
      2
      3
      4
      5
      6
      move.performed += (context) =>
      {
      print("触发事件调用");
      //持续时间
      print(callbackContext.duration);
      };

      输出

      image

    • 开始时间

      操作开始的时间

      1
      2
      3
      4
      5
      6
      move.performed += (context) =>
      {
      print("触发事件调用");
      //开始时间
      print(callbackContext.startTime);
      };

      输出:

      image

特殊输入设置

如果要修改特殊输入的默认值,需要修改Input System Package,它在Project Setting内

如果要修改Input System Package的内容的话,我们需要先创建一个设置的配置文件,点击Create setting asset即可

image

点击后创建这个文件

image

如果要放弃配置文件带来的修改,直接删除创建的文件即可

Input Syetem Package 参数相关

​​​image​​​

  • UpdateMode:更新模式

    • Process Events In Dynamic Update:在动态更新中处理事件
    • Process Events In Fixed Update:在固定更新中处理事件
    • Process Events Manually:手动处理事件
  • Background Behavior:后台行为

    • Reset And Disable Non Background Devices:
      重置和禁用非后台设备
    • Reset And Disable All Devices:重置和禁用所有设备
    • Ignore Focus:忽略焦点
  • Filter Noise on .current:过滤当前设备的噪音

  • Compensate Orientation:定向补偿

  • Default Deadzone Min:默认死区最小值

  • Default Deadzone Max:默认死区最大值

  • Default Button Press Point:默认按钮达到触发按下的点(线性扳机用)

  • Button Release Threshold:按钮释放阈值

  • Default Tap TIme:默认点击时间

  • Default Slow Tap Time:默认慢速点击时间

  • Default Hold Time:默认保持时间

  • Tap Radius:点击半径

  • MultTap Delay TIme:多次点击延迟时间

  • Supported Devices:支持的设备

    如果希望输入系统支持其可以识别的所有输入设备,
    请将支持的设备保留为空。
    但是,如果您只对某一组设备感兴趣,那么在此处添加它们将缩小编辑器中显示的范围,并避免从与项目无关的设备获取输入。
    在此处添加设备时,任何未被分类为受支持的设备都将显示在输入调试器的“不受支持的设备”下

  • Motion Usage:动作使用

  • Description:描述

  • Play Mode Input Behavior:播放模式输入行为

    • Pointers And Keyboards Respect Game View Focus:
      指针和键盘遵守游戏视图焦点
    • All Devices Respect Game View Focus:
      所有设备都遵守游戏视图焦点
    • All Device Input Always Goes To Game View:
      所有设备输入始终进入游戏视图