前言

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);
   |