Unreal 委托与代理
关于声明与特点
事件
- 特点:
- 只有宣称事件的类才能调用事件的Broadcast, IsBound和Clear方法。
- 和多播一样,可以绑定多个回调函数。
- 声明:
DECLARE_EVENT(OwnType, FEventName);
DECLARE_EVENT_OneParam(OwnType, FEventName, int32);
DECLARE_EVENT_TwoParams(OwnType, FEventName, int32, float);
DECLARE_EVENT_ThreeParams(OwnType, FEventName, int32, float, bool);
DECLARE_EVENT_FourParams(OwnType, FEventName, ...);
DECLARE_EVENT_FiveParams(OwnType, FEventName, ...);
DECLARE_EVENT_SixParams(OwnType, FEventName, ...);
DECLARE_EVENT_SevenParams(OwnType, FEventName, ...);
DECLARE_EVENT_EightParams(OwnType, FEventName, ...);
DECLARE_EVENT_NineParams(OwnType, FEventName, ...);
class AMyActor:public AActor
{
GENERATED_BODY()
public:
DECLARE_EVENT_OneParam(ADelegateActor, MyDelegateEvent, int32);
MyDelegateEvent& OnEventTrigger(){return DelegateEvent;}
private:
MyDelegateEvent DelegateEvent;
}
支持的绑定实例类型 |
---|
AddStatic |
AddLambda |
AddWeakLambda |
AddRaw |
AddSP |
AddThreadSafeSP |
AddUObject |
AddUFunction |
单播
- 特点:
- 绑定单个可调用对象。
- 支持返回值。
- 支持参数。
- 不支持反射以及序列化。
- 声明:
DECLARE_DELEGATE(FOnMyDelegate);
DECLARE_DELEGATE_OneParam(FOnMyDelegate, int32);
DECLARE_DELEGATE_TwoParams(FOnMyDelegate, int32, float);
DECLARE_DELEGATE_ThreeParams(FOnMyDelegate, int32, float, bool);
DECLARE_DELEGATE_FourParams(FOnMyDelegate, ...);
DECLARE_DELEGATE_FiveParams(FOnMyDelegate, ...);
DECLARE_DELEGATE_SixParams(FOnMyDelegate, ...);
DECLARE_DELEGATE_SevenParams(FOnMyDelegate, ...);
DECLARE_DELEGATE_EightParams(FOnMyDelegate, ...);
DECLARE_DELEGATE_NineParams(FOnMyDelegate, ...);
DECLARE_DELEGATE_RetVal(ReturnValueType, FOnMyDelegate);
DECLARE_DELEGATE_RetVal_OneParam(ReturnValueType, FOnMyDelegate, int32);
DECLARE_DELEGATE_RetVal_TwoParams(ReturnValueType, FOnMyDelegate, int32, float);
DECLARE_DELEGATE_RetVal_ThreeParams(ReturnValueType, FOnMyDelegate, int32, float, bool);
DECLARE_DELEGATE_RetVal_FourParams(ReturnValueType, FOnMyDelegate, ...);
DECLARE_DELEGATE_RetVal_FiveParams(ReturnValueType, FOnMyDelegate, ...);
DECLARE_DELEGATE_RetVal_SixParams(ReturnValueType, FOnMyDelegate, ...);
DECLARE_DELEGATE_RetVal_SevenParams(ReturnValueType, FOnMyDelegate, ...);
DECLARE_DELEGATE_RetVal_EightParams(ReturnValueType, FOnMyDelegate, ...);
DECLARE_DELEGATE_RetVal_NineParams(ReturnValueType, FOnMyDelegate, ...);
支持的绑定实例类型 |
---|
BindStatic |
BindLambda |
BindWeakLambda |
BindRaw |
BindSP |
BindThreadSafeSP |
BindUObject |
BindUFunction |
动态 单播
- 特点:
- 绑定单个可调用对象,需要
UFUNCTION()
宏修饰绑定函数。 - 支持返回值。
- 支持参数。
- 不支持反射以及序列化。
- 动态单播委托在执行时需要实时在类中按照给定的函数名字查找对应的函数,因此执行速度很慢。
- 声明:
DECLARE_DYNAMIC_DELEGATE(FOnMyDelegate);
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnMyDelegate, int32, val_1);
DECLARE_DYNAMIC_DELEGATE_TwoParams(FOnMyDelegate, int32, val_1, float, val_2);
DECLARE_DYNAMIC_DELEGATE_ThreeParams(FOnMyDelegate, int32, val_1, float, val_2, bool, val_3);
DECLARE_DYNAMIC_DELEGATE_FourParams(FOnMyDelegate, ...);
DECLARE_DYNAMIC_DELEGATE_FiveParams(FOnMyDelegate, ...);
DECLARE_DYNAMIC_DELEGATE_SixParams(FOnMyDelegate, ...);
DECLARE_DYNAMIC_DELEGATE_SevenParams(FOnMyDelegate, ...);
DECLARE_DYNAMIC_DELEGATE_EightParams(FOnMyDelegate, ...);
DECLARE_DYNAMIC_DELEGATE_NineParams(FOnMyDelegate, ...);
DECLARE_DYNAMIC_DELEGATE_RetVal(ReturnValueType, FOnMyDelegate);
DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(ReturnValueType, FOnMyDelegate, int32, val_1);
DECLARE_DYNAMIC_DELEGATE_RetVal_TwoParams(ReturnValueType, FOnMyDelegate, int32, val_1, float, val_2);
DECLARE_DYNAMIC_DELEGATE_RetVal_ThreeParams(ReturnValueType, FOnMyDelegate, int32, val_1, float, val_2, bool, val_3);
DECLARE_DYNAMIC_DELEGATE_RetVal_FourParams(ReturnValueType, FOnMyDelegate, ...);
DECLARE_DYNAMIC_DELEGATE_RetVal_FiveParams(ReturnValueType, FOnMyDelegate, ...);
DECLARE_DYNAMIC_DELEGATE_RetVal_SixParams(ReturnValueType, FOnMyDelegate, ...);
DECLARE_DYNAMIC_DELEGATE_RetVal_SevenParams(ReturnValueType, FOnMyDelegate, ...);
DECLARE_DYNAMIC_DELEGATE_RetVal_EightParams(ReturnValueType, FOnMyDelegate, ...);
DECLARE_DYNAMIC_DELEGATE_RetVal_NineParams(ReturnValueType, FOnMyDelegate, ...);
支持的绑定实例类型 |
---|
BindUFunction |
BindDynamic |
多播
- 特点:
- 绑定多个可调用对象。
- 不支持返回值。
- 支持参数。
- 不支持反射以及序列化。
- 声明:
DECLARE_MULTICAST_DELEGATE(FOnMyDelegate);
DECLARE_MULTICAST_DELEGATE_OneParam(FOnMyDelegate, int32);
DECLARE_MULTICAST_DELEGATE_TwoParams(FOnMyDelegate, int32, float);
DECLARE_MULTICAST_DELEGATE_ThreeParams(FOnMyDelegate, int32, float, bool);
DECLARE_MULTICAST_DELEGATE_FourParams(FOnMyDelegate, ...);
DECLARE_MULTICAST_DELEGATE_FiveParams(FOnMyDelegate, ...);
DECLARE_MULTICAST_DELEGATE_SixParams(FOnMyDelegate, ...);
DECLARE_MULTICAST_DELEGATE_SevenParams(FOnMyDelegate, ...);
DECLARE_MULTICAST_DELEGATE_EightParams(FOnMyDelegate, ...);
DECLARE_MULTICAST_DELEGATE_NineParams(FOnMyDelegate, ...);
支持的绑定实例类型 |
---|
AddStatic |
AddLambda |
AddWeakLambda |
AddRaw |
AddSP |
AddThreadSafeSP |
AddUObject |
AddUFunction |
动态 多播
- 特点:
- 绑定多个可调用对象,
- 在蓝图分配中分配时,使用
UFUNCTION(BlueprintAssignable)
宏修饰绑定函数。 - C++中使用时,使用
UFUNCTION()
宏修饰绑定函数。 - 不支持返回值。
- 支持参数。
- 支持反射以及序列化。
- 声明:
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnMyDelegate);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMyDelegate, int32);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnMyDelegate, int32, val_1, float, val_2);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnMyDelegate, int32, val_1, float, val_2, bool, val_3);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FOnMyDelegate, ...);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FOnMyDelegate, ...);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_SixParams(FOnMyDelegate, ...);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_SevenParams(FOnMyDelegate, ...);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_EightParams(FOnMyDelegate, ...);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_NineParams(FOnMyDelegate, ...);
支持的绑定实例类型 |
---|
AddDynamic |
AddUniqueDynamic |
线程安全 多播
DECLARE_TS_MULTICAST_DELEGATE(FOnMyDelegate);
DECLARE_TS_MULTICAST_DELEGATE_OneParam(FOnMyDelegate, int32);
DECLARE_TS_MULTICAST_DELEGATE_TwoParams(FOnMyDelegate, int32, float);
DECLARE_TS_MULTICAST_DELEGATE_ThreeParams(FOnMyDelegate, int32, float, bool);
DECLARE_TS_MULTICAST_DELEGATE_FourParams(FOnMyDelegate, ...);
DECLARE_TS_MULTICAST_DELEGATE_FiveParams(FOnMyDelegate, ...);
DECLARE_TS_MULTICAST_DELEGATE_SixParams(FOnMyDelegate, ...);
DECLARE_TS_MULTICAST_DELEGATE_SevenParams(FOnMyDelegate, ...);
DECLARE_TS_MULTICAST_DELEGATE_EightParams(FOnMyDelegate, ...);
DECLARE_TS_MULTICAST_DELEGATE_NineParams(FOnMyDelegate, ...);
支持的绑定实例类型 |
---|
AddStatic |
AddLambda |
AddWeakLambda |
AddRaw |
AddSP |
AddThreadSafeSP |
AddUObject |
AddUFunction |
关于如何绑定
前缀Bind、前缀Add
- 首先非动态委托。
Bind + ...
用于绑定单播委托。Add + ...
用于绑定多播的委托或事件。
BindStatic、AddStatic
MyDelegate.BindStatic(&UMyObject::OnMyDelegateStaticFunc);
MyDelegate.AddStatic(&UMyObject::OnMyDelegateStaticFunc);
BindLambda、AddLambda
- 是用于绑定Lambda函数。
- lambda表达式的说明:
- [] - 没有任何函数对象参数。
- [=] - 函数体内可以使用 Lambda 所在范围内所有可见的局部变量(包括 Lambda 所在类的 this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。
- [&] - 函数体内可以使用 Lambda 所在范围内所有可见的局部变量(包括 Lambda 所在类的 this),并且是引用传递方式(相当于是编译器自动为我们按引用传递了所有局部变量)。
- [this] - 函数体内可以使用 Lambda 所在类中的成员变量。
- lambda允许捕捉对象的this指针,但是当多线程处理或者离开作用域等原因,对象的生命期已经结束的情况下,还继续访问lambda函数就会可能会造成比较严重的问题。
MyDelegate.BindLambda([this]() { MyFunction(); });
MyDelegate.AddLambda([this]() { MyFunction(); });
BindWeakLambda、AddWeakLambda
- 是用于绑定Lambda函数。
- 方法需要要在UObject类中使用,非继承自U类的是不能使用的,绑定Lambda表达式并且是持有UObject对象的弱引用。
- 定时器绑代理的时候绑Lambda, 结果this可能是野指针, 如果this无效不会执行lambda。
MyDelegate.BindWeakLambda(this, [this]() { MyFunction(); });
MyDelegate.AddWeakLambda(this, [this]() { MyFunction(); });
BindRaw、AddRaw
- 绑定原始C++指针委托。
- 如果删除了对象,则调用此函数可能不安全。
MyClass* NewClass = new MyClass();
MyDelegate.BindRaw(NewClass, &NewClass::MyFunction)
MyClass* NewClass = new MyClass();
MyDelegate.AddRaw(NewClass, &NewClass::MyFunction)
BindSP、AddSP
TSharedPtr<MyClass, ESPMode::NotThreadSafe> NewClass(new MyClass());
MyDelegate.BindSP(NewClass.ToSharedRef(), &NewClass::MyFunction);
TSharedPtr<MyClass, ESPMode::NotThreadSafe> NewClass(new MyClass());
MyDelegate.AddSP(NewClass.ToSharedRef(), &NewClass::MyFunction);
BindThreadSafeSP、AddThreadSafeSP
TSharedPtr<MyClass, ESPMode::ThreadSafe> NewClass(new MyClass());
MyDelegate.BindThreadSafeSP(NewClass.ToSharedRef(), &NewClass::MyFunction);
TSharedPtr<MyClass, ESPMode::ThreadSafe> NewClass(new MyClass());
MyDelegate.AddThreadSafeSP(NewClass.ToSharedRef(), &NewClass::MyFunction);
BindUFunction、AddUFunction
MyDelegate.BindUFunction(this,"FunctionName");
MyDelegate.AddUFunction(this,"FunctionName");
BindUObject、AddUObject
MyObject->MyDelegate.BindUObject(this, &ThisClass::MyFunction);
MyObject->MyDelegate.AddUObject(this, &ThisClass::MyFunction);
绑定动态
BindDynamic
AddDynamic
AddUniqueDynamic
- 绑定动态多播时使用,增加代理去重功能。
- 如下:情况A调用两次,情况B调用一次。
MyClass->OnEvent.AddDynamic(this, &AMyClassManager::OnEvent);
MyClass->OnEvent.AddDynamic(this, &AMyClassManager::OnEvent);
MyClass->OnEvent.AddUniqueDynamic(this, &AMyClassManager::OnEvent);
MyClass->OnEvent.AddUniqueDynamic(this, &AMyClassManager::OnEvent);
关于如何解除绑定
FDelegateHandle
FDelegateHandle DelegateHandle;
DelegateHandle = MyObject->MyDelegate.AddUObject(this, &ThisClass::MyFunction);
UnBind
MyDelegate.Unbind();
Remove | RemoveAll
MyObject->MyDelegate.Remove(this, &ThisClass::MyFunction);
MyObject->MyDelegate.Remove(DelegateHandle);
MyObject->MyDelegate.RemoveAll();
Clear
MyObject->MyDelegate.Clear();
关于如何调用
IsBound
MyDelegate.IsBound();
Execute | ExecuteIfBound
MyDelegate.ExecuteIfBound();
MyDelegate.Execute();
BroadCast
MyDelegate.Broadcast();