前言
UE4中有茫茫多的代理类型, 对于初学者刚开始都是一头雾水, 本篇文章逐步分析每一种代理的使用方法
我们先用一个输入整形输入参数的形式,声明所有类型的代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| DECLARE_DELEGATE_OneParam(FDlg_1P,int32);
DECLARE_MULTICAST_DELEGATE_OneParam(FDlgMul_1P, int32);
DECLARE_EVENT_OneParam(AActor,FDlgEvent_1P,int32);
DECLARE_DYNAMIC_DELEGATE_OneParam(FDlgDy_1P, int32, number);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDlgDyMul_1P, int32, number);
DECLARE_DELEGATE_RetVal_OneParam(bool,FDlgRet_1P,int32);
DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(bool, FDlgDyRet_1P, int32, number);
|
1 2 3 4 5 6 7 8 9 10
| FDlg_1P Dlg_1P; FDlgMul_1P DlgMul_1P; FDlgEvent_1P DlgEvent_1P; FDlgDy_1P DlgDy_1P;
UPROPERTY(BlueprintAssignable, BlueprintCallable) FDlgDyMul_1P DlgDyMul_1P;
FDlgRet_1P DlgRet_1P; FDlgDyRet_1P DlgDyRet_1P;
|
按使用方式, 一般就是普通的单播代理, 动态代理, 多播代理以及动态多播代理, 每种类型都有无参数很若干参数的版本以及带返回值的版本(多播无返回值);
后续我们也按照蓝图可否使用来区分各个代理
单播代理
1 2
| DECLARE_DELEGATE_OneParam(FDlg_1P,int32); DECLARE_DELEGATE_RetVal_OneParam(bool,FDlgRet_1P,int32);
|
1 2
| FDlg_1P Dlg_1P; FDlgRet_1P DlgRet_1P;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void Event_FDlg_1P(int32 number); Dlg_1P.BindUObject(this, &ATestActor::Event_FDlg_1P); Dlg_1P.Unbind();
bool Event_DlgRet_1P(int32 number); GetFDlgRet_1P().BindUObject(this, &ATestActor::Event_DlgRet_1P);
|
1 2 3 4 5
| Dlg_1P.ExecuteIfBound(number); if (DlgRet_1P.IsBound()) { return DlgRet_1P.Execute(number); }
|
不支持反射以及序列化,可以有返回值,支持Playload参数,可以绑定一个
另外定义的变量无法定义为蓝图变量, 也无法作为参数传递给蓝图;
绑定以后会顶替掉其他绑定的类,即绑定唯一
多播代理/事件
1 2 3 4
| DECLARE_MULTICAST_DELEGATE_OneParam(FDlgMul_1P, int32); DECLARE_EVENT_OneParam(AActor,FDlgEvent_1P,int32); FDlgMul_1P DlgMul_1P; FDlgEvent_1P DlgEvent_1P;
|
1 2 3 4 5 6 7 8 9 10 11 12
| GetFDlgMul_1P().AddUObject(this, &ATestActor::Event_FDlgMul_1P); GetFDlgMul_1P().RemoveAll(this);
|
1
| DlgMul_1P.Broadcast(number);
|
不支持反射以及序列化,无返回值,支持Playload参数,可以绑定多个
动态代理
1 2 3 4
| DECLARE_DYNAMIC_DELEGATE_OneParam(FDlgDy_1P, int32, number); DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(bool, FDlgDyRet_1P, int32, number); FDlgDy_1P DlgDy_1P; FDlgDyRet_1P DlgDyRet_1P;
|
1 2 3 4 5 6
| void Event_FDlgDy_1P(int32 number); GetFDlgDy_1P().BindUFunction(this, TEXT("Event_FDlgDy_1P"));
GetFDlgDy_1P().Unbind();
|
1 2 3 4 5
| GetFDlgDy_1P().Broadcast(number); if (DlgDyRet_1P.IsBound()) { return DlgDyRet_1P.Execute(number); }
|
支持反射以及序列化,可以有返回值,不支持Playload参数,绑定唯一
另外动态代理支持作为蓝图函数的参数, 如下
1 2
| UFUNCTION(BlueprintCallable, BlueprintNativeEvent) bool TestFunction(const FDlgDy_1P& callback_Dy, const FDlgDyRet_1P& callback_DyRet);
|
调用此函数以后也作为唯一绑定而顶替掉原有绑定.
动态多播代理
1 2 3
| DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDlgDyMul_1P, int32, number); UPROPERTY(BlueprintAssignable, BlueprintCallable) FDlgDyMul_1P DlgDyMul_1P;
|
1 2 3
| GetFDlgDyMul_1P().AddDynamic(this, &ATestActor::Event_FDlgDyMul_1P); GetFDlgDyMul_1P().RemoveDynamic(this, &ATestActor::Event_FDlgDyMul_1P);
|
1
| DlgDyMul_1P.Broadcast(number);
|
如果定义的时候加入了BlueprintAssignable, BlueprintCallable
即可以作为蓝图变量, 类似蓝图的Dispatcher
的使用
关于Payload
1 2 3 4 5 6 7 8 9
| DECLARE_DELEGATE_OneParam(FTestDlg, int); static void TestPayload(int number, FString txt) { UE_LOG(LogTemp, Log, TEXT("TestPayload : %d %s"), number, *txt); }
FTestDlg TestDlg; TestDlg.BindStatic(TestPayload, TEXT("Hello")); TestDlg.ExecuteIfBound(2);
|