5.3 KiB
5.3 KiB
UCommandInputComponent
基本信息
- 类型: UCLASS(BlueprintSpawnableComponent, Blueprintable)
- 父类: UEndpointComponent
- 源文件: Plugins/CharacterControl/Source/CharacterControl/Public/CommandInputComponent.h
- 模块: CharacterControl
功能概述
将增强输入(Enhanced Input)动作转换为 FCommandPacket 命令。BeginPlay 将 InputMappingContext 添加到本地玩家子系统,然后从 CommandData 绑定所有 InputAction。BuildPacket 将布尔值/一维轴/二维轴/三维轴值转换为 FVector3f。连续命令使用 Triggered(每帧触发),离散命令使用 Started。OnPacketBuilt 虚函数钩子用于检查/修改。默认跳数限制:连续命令为 3,离散命令为 5。
设计用意
UE 增强输入与基于标签的路由之间的桥梁。将游戏逻辑与输入绑定解耦——系统通过标签订阅而非直接绑定。同一输入可基于状态触发不同响应。跳数限制的差异化反映了频率差异。
职责范围
输入到命令的转换。绑定增强输入动作,将值转换为命令数据包,通过委托输出。不负责路由命令。
项目内依赖
| 依赖项 | 关系 | 源文件 |
|---|---|---|
| EndpointComponent.h | #include (parent) | Plugins/CharacterControl/Source/CharacterControl/Public/EndpointComponent.h |
| UInputCommandData | forward-declare (header) | Plugins/CharacterControl/Source/CharacterControl/Public/CommandInputComponent.h |
| FInputCommand | forward-declare (header) | Plugins/CharacterControl/Source/CharacterControl/Public/CommandInputComponent.h |
| InputCommandData.h | #include (in .cpp) | Plugins/CharacterControl/Source/CharacterControl/Public/InputCommandData.h |
对外接口
UCommandInputComponent 继承 UEndpointComponent,是 Enhanced Input 到命令路由系统的翻译器。挂载到 APlayerController 上,自动加载 InputMappingContext 并将输入动作绑定为命令。
配置属性:
- CommandData (TObjectPtr, EditAnywhere, BlueprintReadOnly): 指向 UInputCommandData 资产,包含要加载的 InputMappingContext 和 FInputCommand 映射列表
可重写方法:
- BuildPacket(const FInputCommand&, const FInputActionInstance&) -> FCommandPacket (virtual): 根据配置和运行时输入值构建命令包。默认实现:Boolean -> ZeroVector/OneVector, Axis1D -> X, Axis2D -> XY, Axis3D -> XYZ。连续命令 HopLimit=3,离散命令 HopLimit=5。C++ 子类可重写自定义构造逻辑
- OnPacketBuilt(const FInputCommand&, FCommandPacket&) (virtual): 钩子函数,在包构建完成、广播之前调用。子类可在此检查、修改或拦截命令包。默认实现为空
继承自 UEndpointComponent 的接口:
- OnCommandReceived、OnEndpointStateChanged、OnCommandOutput、EndpointState 等全部可用。同时自动注册到兄弟 UCommandRouterComponent
使用方法
将 UCommandInputComponent 添加到 PlayerController,配置 CommandData 资产即可:
- BeginPlay 初始化:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandInputComponent.cpp:16-32-- 获取 PlayerController,通过 UEnhancedInputLocalPlayerSubsystem 添加 InputMappingContext,调用 BindAllCommands - EndPlay 清理:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandInputComponent.cpp:34-39-- 调用 UnbindAllCommands 移除所有输入绑定,再调用 Super::EndPlay - BuildPacket:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandInputComponent.cpp:41-80-- 根据动作值类型转换输入值,设置 Meta 和载荷字段 - BindAllCommands:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandInputComponent.cpp:82-116-- 遍历 CommandData->InputCommands,使用 BindActionInstanceLambda 绑定。连续命令用 ETriggerEvent::Triggered,离散命令用 Started - UnbindAllCommands:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandInputComponent.cpp:118-133-- 遍历 BindingHandles 逐一 RemoveBindingByHandle 后清空数组
用例
- 完整输入翻译:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandInputComponent.cpp:96-114-- BindAllCommands 对每个 FInputCommand 绑定 lambda:BuildPacket 构建包 -> OnPacketBuilt 钩子修改 -> OnCommandOutput.ExecuteIfBound 广播。一条输入动作的完整流水线 - 连续命令(Triggered):
Plugins/CharacterControl/Source/CharacterControl/Private/CommandInputComponent.cpp:99-100-- bIsContinuous 为 true 时绑定 ETriggerEvent::Triggered,每帧触发,用于移动、瞄准等模拟量操作 - 离散命令(Started):
Plugins/CharacterControl/Source/CharacterControl/Private/CommandInputComponent.cpp:101-- bIsContinuous 为 false 时绑定 ETriggerEvent::Started,按一次触发一次,用于跳跃、射击等一次性动作 - 输入值类型转换:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandInputComponent.cpp:49-67-- 根据 GetValueType() 将 Boolean/Axis1D/Axis2D/Axis3D 统一转为 FVector3f,实现多类型输入的标准化输出 - InputMappingContext 加载:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandInputComponent.cpp:20-29-- BeginPlay 中通过 UEnhancedInputLocalPlayerSubsystem::AddMappingContext 加载映射上下文