无依赖前提下如何捕获Actor函数执行并同步调用Component函数?
问题描述
我想在Unreal中制作一个Actor组件,要求所属Actor对该组件无依赖,同时要从组件中处理所属Actor的部分事件。我可以通过GetOwner()函数从组件中获取所属Actor的指针:
APlayerController *Controller = Cast<APlayerController>(GetOwner());
也能获取想要处理的函数引用,例如:
&APlayerController::BeginPlay
我也知晓该函数的签名,这是无依赖前提下可获取的全部信息。我希望捕获所属Actor函数的执行,即让组件的另一函数同步执行并接收相同参数。仅靠这些信息是否可行?该如何实现?
更新:纯C++示例(无需Unreal API)
希望ActorFunction执行时,ComponentFunction同步执行且param参数值相同:
class Actor; class Component { Actor *Owner; public: Component(Actor *actor) { Owner = actor; } void ComponentFunction(int param) { } }; class Actor { Component *component; public: Actor() { Component *component = new Component(this); } void ActorFunction(int param) { } }; int main() { Actor *actor = new Actor(); actor->ActorFunction(5); delete actor; return 0; }
解决方案
核心逻辑
要实现Actor无依赖组件,但组件能捕获Actor函数执行并同步响应,关键是让组件通过间接绑定的方式,在Actor目标函数执行时触发自身逻辑,同时保证Actor无需感知组件的存在。
纯C++实现方案(针对更新后的示例)
方案1:基于回调列表的轻量实现
通过给Actor添加回调注册接口,组件在构造时将自身的响应函数注册到Actor的回调列表,Actor执行目标函数时遍历触发所有回调:
#include <functional> #include <vector> class Actor; class Component { Actor* Owner; public: Component(Actor* actor); void ComponentFunction(int param) { // 组件自定义处理逻辑 printf("ComponentFunction 接收到参数: %d\n", param); } }; class Actor { Component* component; // 存储针对ActorFunction的所有回调 std::vector<std::function<void(int)>> ActorFunctionCallbacks; // 原始业务逻辑 void OriginalActorFunction(int param) { printf("ActorFunction 接收到参数: %d\n", param); } public: Actor() : component(new Component(this)) {} ~Actor() { delete component; } void ActorFunction(int param) { // 先执行自身逻辑 OriginalActorFunction(param); // 触发所有注册的回调 for (auto& callback : ActorFunctionCallbacks) { callback(param); } } // 对外提供回调注册接口 void RegisterActorFunctionCallback(std::function<void(int)> callback) { ActorFunctionCallbacks.push_back(callback); } // 给组件提供获取自身指针的接口 Component* GetComponent() { return component; } }; // 组件构造时完成回调注册 Component::Component(Actor* actor) : Owner(actor) { Owner->RegisterActorFunctionCallback( std::bind(&Component::ComponentFunction, this, std::placeholders::_1) ); } int main() { Actor* actor = new Actor(); actor->ActorFunction(5); // 输出: // ActorFunction 接收到参数: 5 // ComponentFunction 接收到参数: 5 delete actor; return 0; }
方案2:成员函数指针包装(更贴近Unreal函数引用场景)
如果需要直接绑定Actor的成员函数引用,可以用模板和函数包装的方式,实现更精准的监听:
#include <functional> class Actor; class Component { Actor* Owner; public: Component(Actor* actor); void ComponentFunction(int param) { printf("ComponentFunction 接收到参数: %d\n", param); } }; class Actor { Component* component; void (*WrappedFunc)(Actor*, int) = nullptr; void OriginalActorFunction(int param) { printf("ActorFunction 接收到参数: %d\n", param); } public: Actor() : component(new Component(this)) {} ~Actor() { delete component; } void ActorFunction(int param) { OriginalActorFunction(param); if (WrappedFunc) { WrappedFunc(this, param); } } void SetWrappedFunction(void (*func)(Actor*, int)) { WrappedFunc = func; } Component* GetComponent() { return component; } }; Component::Component(Actor* actor) : Owner(actor) { // 绑定组件逻辑到Actor的包装函数 Owner->SetWrappedFunction([](Actor* actor, int param) { actor->GetComponent()->ComponentFunction(param); }); } int main() { Actor* actor = new Actor(); actor->ActorFunction(5); delete actor; return 0; }
Unreal环境适配思路
Unreal本身提供了成熟的**委托(Delegate)**系统,实现起来更便捷:
- 组件通过
GetOwner()获取Actor指针,利用Unreal反射系统找到目标函数的委托(或动态创建多播委托)。 - 将组件的
ComponentFunction绑定到该委托上,Actor执行目标函数时触发委托,同步执行组件逻辑。 - 借助Unreal的UFunction反射,即使Actor没有显式定义委托,组件也可以动态绑定到Actor的函数触发点,完全满足“Actor无依赖组件”的要求。
内容的提问来源于stack exchange,提问作者Iván Rodríguez
相关产品推荐
相关产品推荐

