This commit is contained in:
meishibiezb
2026-06-04 21:37:53 +08:00
parent b0d2a0e2e7
commit 29a3f77908
63 changed files with 4068 additions and 1 deletions

View File

@@ -0,0 +1,56 @@
# UCommandInputComponent
## 基本信息
- **类型**: UCLASS(BlueprintSpawnableComponent, Blueprintable)
- **父类**: UEndpointComponent
- **源文件**: Plugins/CharacterControl/Source/CharacterControl/Public/CommandInputComponent.h
- **模块**: CharacterControl
## 功能概述
Translates Enhanced Input actions into FCommandPacket commands. BeginPlay adds InputMappingContext to local player subsystem, then binds all InputActions from CommandData. BuildPacket converts Boolean/Axis1D/Axis2D/Axis3D values to FVector3f. Continuous commands use Triggered (every frame), discrete use Started. OnPacketBuilt virtual hook for inspection/modification. Default hop limits: 3 continuous, 5 discrete.
## 设计用意
Bridge between UE Enhanced Input and tag-based routing. Decouples gameplay logic from input bindings - systems subscribe to tags instead. Same input can trigger different responses based on state. Hop limit differentiation reflects frequency differences.
## 职责范围
Input-to-command translation. Binds Enhanced Input actions, converts values to command packets, outputs via delegate. Does NOT route commands.
## 项目内依赖
| 依赖项 | 关系 | 源文件 |
|--------|------|--------|
| 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 绑定 lambdaBuildPacket 构建包 -> 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 加载映射上下文