UE输入系统
增强输入
Enhanced Input System
是对默认输入系统做了一个扩展,它以模块化的方式解耦了从输入的按键配置到事件处理的逻辑处理过程,提供了更灵活和更便利的输入配置和处理功能。同时又能向后兼容虚幻引擎 4 (UE4)中的默认输入系统。以插件的形式供我们使用。
重要的类:
UInputAction
输入操作,简称IA
- 是交互角色可能做出的任何动作,独立于原始输入,可以设置多种类型的输入值
UInputMappingContext
输入映射上下文, 简称IMC
- 将用户的输入映射到操作,并可以动态地为每个用户添加、移除或安排优先次序。通过**本地玩家子系统
UEnhancedInputLocalPlayerSubsystem
将一个或多个映射应用到本地玩家,并安排它们的优先次序,避免多个操作由于尝试使用同一输入而发生冲突
- 将用户的输入映射到操作,并可以动态地为每个用户添加、移除或安排优先次序。通过**本地玩家子系统
UInputModifier
输入修饰符。简称IM
- 调整来自用户设备的原始输入的值,如使用 Negate 可以将输入值取负值。
UInputTrigeer
输入触发器。简称IT
- 根据特定的条件来确定是否应该激活输入操作。
增强输入系统优点
统一案件绑定: Axis/Action —> Action(统一)
运行时重新映射输入场景: UInputMappingContext
对初级用户易配置。大量默认行为实现,Tap/Hold…
对高级用户易扩展,可继承子类扩展
修改器:修改输入值
触发器:决定触发条件
优先级:配置输入场景优先级
模块化,不再只依赖 Ini 配置,以资源 asset 方式配置,堆栈式分隔逻辑
提高性能,不需要检查所有
蓝图与 C++实现
可以参考引擎的模板 Character
创建 InputAction
创建 InputMappingContext
添加输入映射上下文
在 PlayerController
添加创建的输入映射上下文,可以添加多个上下文 !
1 | class ATestPlayerController : public APlayerController |
使用 InputAction 事件
在蓝图中调用事件很简单:
在 C++实现如下,需要将需要绑定的 InputAction 一一声明,然后在角色蓝图中设置调用:
1 | protected: |
在 SetupPlayerInputComponent()
中绑定委托回调
1 | void ATestPlayerController::SetupPlayerInputComponent() |
单独对 Looking 的委托绑定进行解析,我们可以从中看出 C++和蓝图实现的关联 :
1 | //Looking |
BindAction 参数解析:
LookAction
:要绑定的 InputActionETriggerEvent:: Triggered
对应蓝图节点的 Triggered- 最后一个参数:触发 Triggered 时的回调函数。
回调函数解析:
- 通过
Value. Get<T>
输入值,类型是由 IA 中的 ValueType 指定 - 然后就可以根据输入值执行游戏逻辑了
增强输入用法:控制角色跳跃与移动
Input Action
定义一个 InputAction
,等同于一个自定义事件,声明输出值类型、触发时机,Modifier
可用于调整输出值
新建 IA_Jump
和 IA_Move
:
IA_Jump
定义 bool 输出值:
控制跳跃只需要一个 bool 值或浮点数(一个轴的值)即可IA_Move
定义 2D 向量(两个轴的值)输出值,通过获取 x 轴与 y 轴值来分别控制左右移动与前后移动
也可以通过定义两个浮点数的 InputAction 来分别控制左右移动与前后移动
Input Mapping Context (IMC)
IMC 定义 IC 与按键的绑定关系,实现按键触发动作事件
在 IMC 中也可以添加约束:触发器、修改器,和 IC 中的触发器、修改器会叠加生效,下面会详细说明
- 负责将用户的输入映射成输入操作,与按键强相关。
- 可以根据用户需求动态增减或调整优先级,要用分层、堆栈的思想看待 IMC。
- 应用场景:某个按钮既可以用来打开场景中的门,又可以用来拾取背包中的道具。
- 通过 InputMappingContexts,当角色靠近门时,你可以添加 “开门” 这个上下文。假如角色打开背包,你可以添加 “选择道具” 这个输入映射上下文,并且让它的优先级高于 “开门”。
- 可以通过增强输入本地玩家子系统(Enhanced Input Local Player Subsystem)将一个或多个上下文应用到本地玩家身上,并调整它们的优先级
- 两种方式屏蔽某个动作:1. 优先级 2. 配 key 不给 Action
新建 IMC_Default
空格控制跳跃,AD 控制左右移动,WS 控制前后移动
角色蓝图
角色蓝图添加动作映射:
通过 Enhanced Input Local Player Subsystem,将玩家控制器与 IMC 绑定,绑定后 IMC 能够获取到玩家控制器的输入。IMC 再根据输入按键匹配 IA ,触发回调。
蓝图可以添加多个 IMC,priority 高的起作用
蓝图添加按键监听:
事件名即 IA 文件名,在 IMC 中一一对应
IA_Move 的输出值是一个二维向量,可以拆分成 x 轴与 y 轴: Action ValueX
、 Action Value Y
按键 D 声明获取默认值,输出值为 x=1, y=0 的二维向量
按键 A 声明获取相反值,输出值为 x=-1, y=0 的二维向量
按键 W 声明交换输入轴的值,默认的 XYZ,将交换后输出 YXZ,事件回调输出值为 x=0, y=1 的二维向量
按键 S 声明交换输入轴的相反值,默认的 XYZ,将交换后输出 YXZ,事件回调输出值为 x=0, y=-1 的二维向量
对于 EnhancedInputAction IA_move 事件而言,它负责监听按键,当按键输入与 IMC 表上声明的按键匹配,事件触发,在回调中返回输出值,输出 IC 中定义好的值。
优化角色移动:
上下旋转镜头后,角色移动会变慢,因为角色正前方的向量被分解了
所以只获取正前方的向量值
旋转镜头角色不跟着旋转:
use controller rotation yaw 要取消勾选
补充:镜头旋转
IA_Look:
通过 2D 轴值输出 XY 轴向数值
IMC_Default:
Y 轴值取反,使镜头上下旋转的方向与鼠标方向一直
角色蓝图,X 轴控制左右旋转,Y 轴控制上下旋转
设置机械臂:
允许鼠标进行旋转控制,否则上下旋转不生效
解析
新建 IA_test 用于测试
IMC:
角色蓝图:
查看在事件开始、结束与触发过程中的输出值
InputAction
Cosume Input
:这个操作应该吞下绑定到它的任何输入,还是允许它们通过来影响低优先级绑定操作?Trigger When Paused
:是否可以在游戏暂停时触发Reserve All Mappings
:此操作的映射不会被高优先级上下文映射自动重载。用户必须首先显式移除映射。注意∶这由映射代码作者负责强制执行!
Value Type
Value Type
对应事件的返回值类型
Value Type / Time | Triggered | Started | Ongoing | Canceled | Completed |
---|---|---|---|---|---|
Digital (bool) | true | true | false | ||
Axis1D (float) | 1 | 1 | 0 | ||
Axis2D (vector2D) | (1,0) | (1,0) | (0,0) | ||
Axis3D (Vector) | (1,0,0) | (1,0,0) | (0,0,0) |
InputModifier
调整来自用户设备的原始输入的值
Negate
:轴值取反SwizzleInputAxisValues
:互换轴值,当输入值为两个轴以上的时候,可以将输出值顺序从 XYZ 调整为其他顺序 (比如 XYZ 调整为 YXZ,那么输出的 Vector 值从(x: 1,y: 2,z:3)变为 (x: 2, y: 1, z:3))),输出值若为一个轴或 bool 值,将无法获得输出值
Scalar
:缩放
注意:此处对修改器的顺序有要求,对调轴值后,输出值在 Y 轴,此时对 Y 轴进行缩放才有效,否则无效
其他的修改器有(多与摇杆有关,具体可向 GPT 提问):
DeadZone
: 限定触发值的范围FOVScaling
: FOV 缩放CurveExponential
:指数曲线,XYZCurveUser
:自定义指数曲线,CurveFloatSmooth
:多帧之间平滑ToWorldSpace
:输入设备坐标系向世界坐标系转换
当将修改器设置为 ToWorldSpace 时,输入设备的输入值将被转换为世界空间(World Space)中的向量,而不是相对于游戏角色的本地空间(Local Space)中的向量。这意味着,无论游戏角色朝向何方,输入设备的输入值都将产生相同的效果,从而减少了玩家在控制角色时需要考虑本地坐标系的复杂性。
举例来说,如果你将一个摇杆的输入值(X,Y)转换为世界空间中的向量,那么这个向量的方向将与摇杆的偏移方向相同,但是大小将根据摇杆的偏移量来确定。这个向量的大小可以通过修改器的 Scale 属性进行缩放,从而控制游戏角色的移动速度。
需要注意的是,将修改器设置为 ToWorldSpace 可能会对游戏的响应速度产生一定的影响,因为它需要对输入值进行矩阵变换以将其从本地空间转换到世界空间。同时,ToWorldSpace 的效果也可能会因不同的游戏和输入设备而有所不同。
IMC 与 IA 可同时设置 IM、IT
修改器和触发器可以在 Maping 和 InputAciton 中同时设置:
Mapping. Modifiers / Triggers :针对当前 IMC 场景,和按键强相关的
InputAction. Modifiers / Triggers: 针对全局,不需要关心按键,主要关心值怎么动,处理逻辑相关的,
执行顺序:先 IMC 后 IC
InputTrigger
默认使用的是 Down
类型
- 按下:触发 Started
- 保持:不断触发 Triggered
- 松开:触发 Completed
Down
:可用于机枪的连续射击,Started 开始射击,Triggered 检查子弹数量,Completed 停止射击,- 按下:触发 Started
- 保持:不断触发 Triggered
- 松开:触发 Completed
Pressed
:- 按下:依次触发 Started、Triggered 与 Completed
- 保持:无
- 松开:无
Hold
:Hold Time Threshold
:保持多久触发 Triggered 事件Affected by Time Dilation
:Hold Time Threshold
是否受全局时间膨胀影响IsOneShot
:只触发一次,还是每帧触发?IsOneShot
没有勾选,每帧触发:可用于按下保持一段时间,松开才会触发的动作。如吃鸡里手雷投掷。-- 按下:触发 Started
- 保持:不断触发 Ongoing,超过
Hold Time Threshold
后不断触发 Triggered - 松开:如果保持的时间达到或超过
HoldTimeThreshold
设置的时间则触发 Completed,否则触发 Canceled。
IsOneShot
勾选:用于按下保持一段时间后自动触发的动作,如 CS 里拆包。
- 按下:触发 Started
- 保持:不断触发 Ongoing
- 没有达到
HoldTimeThreshold
提前松开:触发 Canceled。 - 达到
HoldTimeThreshold
:自动依次触发 Triggered 与 Completed。
Release
:- 按下时触发 Started 事件
- 保持按下触发 Ongoing 事件
- 松开时依次触发 Triggered 与 Completed
HoldAndRelease
:- 按下:触发 Started
- 保持:不断触发 Ongoing
- 松开:时如果保持的时间达到 HoldTimeThreshold 设置的时间会依次触发 Triggered 与 Completed,否则触发 Canceled。
Pulse
:用于保持按下时每隔一段时间触发一次的动作。如按下吃药键,每隔一段时间执行一次吃药的动作- 按下:触发 Started 事件
- 如果勾选 TriggerOnStart 则立即触发一次 Triggered 事件,不勾选则间隔一段时间后触发 Triggered。
- 保持:触发 Ongoing 事件。
- 距上一次 Trigger 的时间间隔达到 Interval 设置的时间触发一次 Triggered 事件,随后判断 Trigger 触发的数量是否达到 TriggerLimit 的限制 (TriggerLimit<=0 表示不限制次数),未达到则继续上一步,否则触发 Completed。
Tap
按下后快速抬起(默认 0.2):- 按下按键触发 Started 事件
- 保持按下触发 Ongoing 事件
- 如果保持的时间超过 TapReleaseTimeThreshold 设置的时间触发 Canceled 事件。
- 松开按键时保持的时间小于 TapReleaseTimeThreshold 设置的时间依次触发 Triggered 与 Completed 事件。
Chorded Action
:用于多个 Action 的串联形成组合键。按键 1 的 IA 绑定了两个铉操作(按键设置分别为2、3),我们只讨论该 IA 的触发逻辑(绑定的两个铉操作也会执行自己的触发逻辑,这里忽略)
1. 只按 1:无
2. 按 1+2 或 1+3:
- 按下:触发 started
- 保持:触发 Ongoing
- 松开:触发 Canceled
3. 按 1+2+3:
- 按下:触发 started
- 保持:触发 Triggered
- 松开 1:触发 completed
- 松开 2 或 3 其中之一:触发 Ongoing
- 松开 2+3,触发CancelCombo
:用于类似上上下下左右左右 BABA 在短时间内完成的组合键。- 按下第一个键触发 Started
- 过程当中不断触发 Ongoing
- 如果某个键按下的时间没有达到 TimeToPressKey 或者按错键触发 Canceled
- 当所有的键完成后依次触发 Triggered 与 Completed
IT 设置 Combo 后,不需要按键触发,是通过 IC 组合来触发 示例:按下 AABBCC 触发:
Debug
命令行输入
showdebug enhancedinput
最佳实践
[中文直播]第39期 | 虎跳龙拿–新一代增强输入框架EnhancedInput | Epic 大钊_哔哩哔哩_bilibili
IMC BindAction
- 初始情况应该在哪里开始应用 IMC
- 后续运行时在蓝图中如何切换 IMC
- 何时 Remove IMC
- 在哪里绑定 Action 和 Axis
- 在蓝图中如何 BindAction
5.1 初始情况应该在哪里开始应用 IMC
5.2 何时 Remove IMC
5.3 IMC BindAction 最佳实践
5.4 Debug
默认输入系统
轴映射与动作映射
轴映射每帧执行,动作映射一次性执行
1 | void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) |
- 设置按键再游戏暂停可以继续响应
bExecuteWhenPaused
1 | InputComponent->BindAction("ESCEvent", IE_Pressed, this, &ASLAiPlayerController::ESCEvent).bExecuteWhenPaused=true;//游戏暂停可以执行 |
从C++中添加轴和动作映射
1 | //添加、绑定ActionKeyMapping轴映射 方法一 |