4.5 KiB
4.5 KiB
UCommandRouterComponent
基本信息
- 类型: UCLASS(BlueprintSpawnableComponent, Blueprintable)
- 父类: UActorComponent, implements ICommandEndpoint
- 源文件: Plugins/CharacterControl/Source/CharacterControl/Public/CommandRouterComponent.h
- 模块: CharacterControl
功能概述
UCommandRouter 的 ActorComponent 包装器。创建 InternalRouter 作为默认子对象。通过将所有方法委托给 InternalRouter 来实现 ICommandEndpoint。BeginPlay 调用 AutoRegisterEndpoints,自动发现同 Actor 上的 ICommandEndpoint 同级组件并进行注册,跳过自身和已注册的端点。
设计用意
无需 C++ 即可在 Actor 上挂载命令路由器的桥梁。自动注册实现"本地总线"模式:同一 Actor 上的所有端点组件自动通过此路由器连线。设计者添加组件 → 自动形成本地命令总线。
职责范围
附加到 Actor 的路由器宿主。拥有并委托给 UCommandRouter。自动发现并注册同级端点。不实现路由逻辑(委托给 InternalRouter)。
项目内依赖
| 依赖项 | 关系 | 源文件 |
|---|---|---|
| CommandEndpoint.h | #include | Plugins/CharacterControl/Source/CharacterControl/Public/CommandEndpoint.h |
| CommandRouter.h | #include | Plugins/CharacterControl/Source/CharacterControl/Public/CommandRouter.h |
对外接口
UCommandRouterComponent 是将 UCommandRouter 挂载到 Actor 上的组件包装器。实现 ICommandEndpoint 接口(全部委托给 InternalRouter),使得挂载此组件的 Actor 本身可作为端点参与上级路由。
- InternalRouter (TObjectPtr, EditAnywhere, BlueprintReadOnly, Instanced): 暴露给蓝图的设计时属性,可在组件详情面板中查看/配置路由器的端点状态。作为默认子对象通过 CreateDefaultSubobject 创建
- 实现 ICommandEndpoint: GetEndpointState、GetStateChangedDelegate、GetCommandOutputDelegate、ReceiveCommand 全部直接委托给 InternalRouter 的同名方法。这意味着对 UCommandRouterComponent 调用 ReceiveCommand 等价于向 InternalRouter 注入命令
UCommandRouterComponent 的核心价值在于 BeginPlay 自动调用 AutoRegisterEndpoints()。不需要手动注册端点 -- 只需将 UEndpointComponent 或 UCommandInputComponent 作为兄弟组件添加到同一 Actor 上,BeginPlay 时自动发现并注册。
使用方法
UCommandRouterComponent 是"即插即用"的本地命令总线:
- 创建默认子对象:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandRouterComponent.cpp:15-- 构造函数中CreateDefaultSubobject<UCommandRouter>("InternalCommandRouter") - BeginPlay 自动注册:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandRouterComponent.cpp:20-24-- BeginPlay 调用 Super::BeginPlay 后立即执行 AutoRegisterEndpoints - 自动发现:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandRouterComponent.cpp:27-43-- 遍历 Owner 的所有 UActorComponent,通过Implements<UCommandEndpoint>()检查,跳过自身和已注册(委托已绑定)的端点,其余全部注册 - 端点自注册:
Plugins/CharacterControl/Source/CharacterControl/Private/EndpointComponent.cpp:22-42-- UEndpointComponent::BeginPlay 也会主动查找兄弟 UCommandRouterComponent 并注册 - 端点间通信: 注册后的端点通过路由器互相收发命令。端点 A 调用 OutputCommand -> Router 接收 -> 匹配 -> 投递到端点 B 的 ReceiveCommand
用例
- Actor 本地命令总线: 在 Character 蓝图上添加 UCommandRouterComponent + UCommandInputComponent + UEndpointComponent(蓝图子类),BeginPlay 时自动完成连线,输入组件产出的命令自动匹配到端点组件
- 自动注册兄弟端点:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandRouterComponent.cpp:31-42-- AutoRegisterEndpoints 遍历所有兄弟组件,调用 Implements() 检查接口实现,将未注册的端点通过 InternalRouter->RegisterEndpoint 注册 - 跳过已注册端点:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandRouterComponent.cpp:40-- 通过GetCommandOutputDelegate().IsBound()判断端点是否已注册(委托已绑 = 已注册),避免重复注册 - 以路由器作为端点参与上级路由: 由于 UCommandRouterComponent 实现 ICommandEndpoint 且全部委托给 InternalRouter,其他 Actor 上的上级路由器可以通过 TScriptInterface 将此组件注册为端点