57 lines
5.3 KiB
Markdown
57 lines
5.3 KiB
Markdown
# 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<UInputCommandData>, 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 加载映射上下文
|