5.3 KiB
ICommandEndpoint
基本信息
- 类型: UINTERFACE + C++ interface
- 父类: UInterface
- 源文件: Plugins/CharacterControl/Source/CharacterControl/Public/CommandEndpoint.h
- 模块: CharacterControl
功能概述
命令路由图中所有节点的中央抽象层。纯虚方法:GetEndpointState、GetStateChangedDelegate、GetCommandOutputDelegate、ReceiveCommand。BlueprintNativeEvent:ReceiveCommand_BP、GetEndpointDispatcher_BP。默认 C++ 实现通过调度器为蓝图子类提供路由,而 C++ 子类直接重写。
设计用意
统一接口,使异构路由图成为可能。路由器管理 ICommandEndpoint 集合,无需知晓具体类型。调度器模式解决了 UE 的限制——BlueprintNativeEvent 无法直接返回委托引用。
职责范围
定义命令路由参与者的契约。所有路由器、端点组件和输入组件均实现此接口。所有命令类型的单一 ReceiveCommand 入口点。
项目内依赖
| 依赖项 | 关系 | 源文件 |
|---|---|---|
| FEndpointState | 返回类型 (GetEndpointState) | Plugins/CharacterControl/Source/CharacterControl/Public/CommandEndpoint.h |
| FCommandPacket | 参数类型 (ReceiveCommand) | Plugins/CharacterControl/Source/CharacterControl/Public/CommandEndpoint.h |
| UEndpointDispatcher | 返回类型 (GetEndpointDispatcher_BP) | Plugins/CharacterControl/Source/CharacterControl/Public/CommandEndpoint.h |
对外接口
ICommandEndpoint 是命令路由图中所有参与者的统一抽象接口。任何希望接收或产出命令的对象都需要实现此接口。接口包含四个 C++ 纯虚方法和两个 BlueprintNativeEvent。
C++ 纯虚方法(C++ 子类直接重写):
- GetEndpointState() -> const FEndpointState&: 返回端点的身份和配置状态。UCommandRouter::RegisterEndpoint 以此获取 GUID 和 InterestedTags
- GetStateChangedDelegate() -> FOnEndpointStateChanged&: 返回状态变更委托引用。Router 通过 BindDynamic 订阅,当端点状态变化时触发标签聚合更新
- GetCommandOutputDelegate() -> FOnCommandOutput&: 返回命令输出委托引用。Router 订阅以接收端点产出的命令,转发给其他端点
- ReceiveCommand(const FCommandPacket&): 接收命令的统一入口。Router 调用此方法向匹配的端点投递命令
BlueprintNativeEvent(蓝图子类重写):
- ReceiveCommand_BP(const FCommandPacket&): 蓝图端点的命令接收入口。C++ 默认实现通过调度器桥接调用此事件
- GetEndpointDispatcher_BP() -> UEndpointDispatcher*: 蓝图端点返回调度器实例。C++ 默认实现通过此方法获取委托引用
默认实现策略:C++ 默认实现(CommandEndpoint.cpp:8-26)全部通过 Execute_GetEndpointDispatcher_BP 获取 UEndpointDispatcher,然后委托执行。这意味着蓝图类(如 UEndpointComponent_BP 子类)必须重写 GetEndpointDispatcher_BP 并返回有效调度器。C++ 类(UCommandRouter、UCommandRouterComponent、UEndpointComponent)则直接重写纯虚函数,不使用调度器。
使用方法
ICommandEndpoint 是接口而非具体类,通过 TScriptInterface 在多处使用:
- 路由器注册:
Plugins/CharacterControl/Source/CharacterControl/Public/CommandRouter.h:37-- RegisterEndpoint 接受TScriptInterface<ICommandEndpoint>,从接口获取端点状态、委托并完成注册 - 路由器实现:
Plugins/CharacterControl/Source/CharacterControl/Public/CommandRouter.h:14-- UCommandRouter 实现此接口,作为端点参与上级路由器的路由 - 组件实现:
Plugins/CharacterControl/Source/CharacterControl/Public/CommandRouterComponent.h:14-- UCommandRouterComponent 实现此接口,委托给 InternalRouter - 端点组件实现:
Plugins/CharacterControl/Source/CharacterControl/Public/EndpointComponent.h:13-- UEndpointComponent 实现此接口,作为蓝图端点的基类 - 默认 C++ 实现:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandEndpoint.cpp:8-26-- 所有纯虚函数的默认实现,通过调度器桥接蓝图
用例
- Router 实现端点的 ReceiveCommand:
Plugins/CharacterControl/Source/CharacterControl/Public/CommandRouter.h:22-25-- UCommandRouter 直接重写 ReceiveCommand、GetEndpointState、GetStateChangedDelegate、GetCommandOutputDelegate,不使用调度器桥接 - EndpointComponent 实现端点的 ReceiveCommand:
Plugins/CharacterControl/Source/CharacterControl/Public/EndpointComponent.h:30-33-- UEndpointComponent 直接重写纯虚方法,ReceiveCommand 转调 BlueprintImplementableEvent OnCommandReceived - 端点注册入口:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandRouter.cpp:45-84-- RegisterEndpoint 通过 TScriptInterface 获取端点的 EndpointGuid、委托,绑定状态变更和命令输出回调,执行标签聚合 - 自动发现注册:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandRouterComponent.cpp:37-41-- AutoRegisterEndpoints 遍历 Actor 组件,通过Implements<UCommandEndpoint>()检查并注册所有实现接口的兄弟组件 - 蓝图桥接:
Plugins/CharacterControl/Source/CharacterControl/Private/CommandEndpoint.cpp:23-26-- 蓝图类没有重写 ReceiveCommand 时,C++ 默认实现调用 Execute_ReceiveCommand_BP,由蓝图元数据系统查找蓝图重写