【UE4笔记】各种Delegate委托的区别和应用

UE4委托

委托的基本类型有三种:

  1. 单播委托
  2. 多播委托
  3. 动态委托

单播委托

单播委托指只能绑定一个函数指针的委托,也就是当执行委托时只能触发一个唯一绑定的函数。
单播委托可以绑定一个无返回值或有返回值的函数。

//无返回值函数委托声明
DECLARE_DELEGATE(DelegateName);			//无参
DECLARE_DELEGATE_OneParam(DelegateName, Param1Type);	//1个参数
DECLARE_DELEGATE_XXXParams(DelegateName, Param1Type, ...);	//多参
//有返回值函数委托声明
DECLARE_DELEGATE_RetVal(RetValType, DelegateName);	//有返回值无参
DECLARE_DELEGATE_RetVal_OneParam(RetValType, DelegateName, Param1Type);	//有返回值,1个参数
DECLARE_DELEGATE_RetVal_XXXParams(RetValType, DelegateName, Param1Type, ...);	//有返回值,多参

声明单播委托

DECLARE_DELEGATE(FTestDelegate);
class XXX_API AMyTestActor : public AActor
{
	GENERATED_BODY()
public:	
	AExecuteDelegateActor();
protected:
	virtual void BeginPlay() override;
public:	
	virtual void Tick(float DeltaTime) override;
public:
	//单播委托不能声明BlueprintAssignable标识符。动态多播可以声明BlueprintAssignable
	FTestDelegate TestDelegate;
}

将函数绑定到单播委托

函数描述
BindSP绑定SharedPtr指向对象的函数,即纯C++类的函数。因为纯C++类一般会使用TSharedPtr用于管理内存。
BindThreadSafeSP绑定线程安全的共享成员函数委托
BindRaw纯C++类变量,可以用其绑定委托
BindUFunction如果成员函数有UFUNCTION宏表示,可用此绑定委托
BindUObject绑定继承UObject类的成员函数委托
BindStatic绑定静态(全局)函数委托,BindStatic(&MyClass::StaticFunc);
BindLambda绑定一个Lambda函数
BindWeakLambda绑定弱引用Lambda函数
UnBind取消绑定委托
//绑定纯C++类函数到委托
TSharedRef<FMyClass> MyClassObj(new FMyClass());
TestDelegate.BindSP(MyClassObj, &FMyClass::XXXFunc);

//绑定UObject子类函数到委托
TestDelegate.BindUObject(this, &UMyUObjectClass::XXXFunc);		//当前类内绑定
UMyUObjectClass* MyUObjectClassObj;								//其它类内绑定
TestDelegate.BindUObject(MyUObjectClassObj, &UMyUObjectClass::XXXFunc);

委托调用

函数说明
IsBound检查是否绑定一个委托
Execute不检查绑定而执行委托
ExecuteIfBound当绑定一个委托时,执行调用

多播委托

多播委托可以绑定多个函数,但不能有返回值。
事件是特殊类型的多播委托,它在访问Broadcast()、IsBound()、Celar()函数时受限。

//多播委托
DECLARE_MULTICAST_DELEGATE(DelegateName);
DECLARE_MULTICAST_DELEGATE_ONEPARAM(DelegateName, Param1Type);
DECLARE_MULTICAST_DELEGATE_XXXPARAMS(DelegateName, Param1Type,...);

//动态多播委托
DECLARE_DYNAMIC_MULTICAST_DELEGATE(DelegateName);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ONEPARAM(DelegateName, Param1Type, Param1Name);
...

绑定多播委托

函数说明
Add()绑定类型参见单播委托,不同之处就是可以绑定多个函数
AddStatic()
AddRaw()
AddSP()
AddUObject()
Remove()
RemoveAll()

多播执行

Broadcast调用后,会执行所有绑定的委托,但是委托的执行顺序尚未定义。

函数说明
Broadcast()执行所有绑定的委托

动态委托

动态委托可以序列化,其函数可以按命名查找,但执行速度比常规委托慢。

动态及动态多播委托的声明宏结尾必须要有分号,所以建议给所有委托都加分号,这样可以统一样式。

//动态委托
DECLARE_DYNAMIC_DELEGATE(DelegateName);
DECLARE_DYNAMIC_DELEGATE_ONEPARAM(DelegateName, Param1Type);
DECLARE_DYNAMIC_DELEGATE_XXXPARAMS(DelegateName, Param1Type,...);

//动态多播委托,可以暴露给蓝图的委托时动态多播委托
DECLARE_DYNAMIC_MULTICAST_DELEGATE(DelegateName);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ONEPARAM(DelegateName, Param1Type, Param1Name);

动态委托变量(属性)可以作为函数的参数,当我们在蓝图调用函数的同时,可以绑定一个委托了。

DECLARE_DYNAMIC_DELEGATE(FMyDynamicDelegate);

public:
	//不能声明为蓝图实现函数,cpp文件必须有实现
	UFUNCTION(BlueprintCallable)
	void DynDelTestFunc(FMyDynamicDelegate MyDynamicDelegate)
	{	//这里为方便说明,直接在声明处定义
		//调用出入的动态委托
		MyDynamicDelegate.ExecuteIfBound();
	}
	
public:
	FMyDynamicDelegate MyDynamicDelegate;

如下图为调用允许绑定动态委托的函数,这就是上面代码的成果:
调用允许绑定动态委托的函数

绑定动态委托

函数说明
BindDynamic(UserObject, FuncName)用于在动态委托上调用BindDynamic()的辅助宏。自动生成函数命名字符串。
AddDynamic(UserObject, FuncName)
RemoveDynamic(UserObject, FuncName)

执行动态委托

函数说明
IsBound()用法与单播委托相同,见单播委托
Execute()
ExecuteIfBound()

动态多播委托

动态多播委托可以暴露给蓝图使用,并且声明宏中不仅包含变量类型,也包含变量名。如果暴露给蓝图,需要给委托变量的UPROPERTY宏添加BlueprintAssignable标识符

DECLARE_DYNAMIC_MULTICAST_DELEGATE(DelegateName);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ONEPARAM(DelegateName, Param1Type, Param1Name);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_XXXPARAM(DelegateName, Param1Type, Param1Name,...);

委托声明示例:

DECLARE_DYNAMIC_MULTICAST_DELEGATE_ONEPARAM(FDelegateTest, class AActor*, MyActor);

UPROPERTY(BlueprintAssignable)
FDelegateTest TestDelegate;

应用场景总结

  1. 单播委托: 当我们只需要在C++中绑定和调用,且只有一个函数需要绑定委托时,可以使用单播委托。
    当然,这个委托的绑定和调用可以通过二次函数调用暴露给蓝图。就是绑定和调用的函数再包裹一层,但一般没有必要。
    一般常用的就是函数回调时,通过绑定到单播委托进行回调。

  2. 多播委托: 单播和多播最大不同就是多播可以绑定多个函数,且不能有返回值,其它功能与单播委托一样。

  3. 动态委托: 顾名思义,就是允许动态绑定,它可以序列化,也就是说可以在蓝图中使用,下面再回顾一下应用场景。
    我们可以将动态委托作为变量,在函数中对委托调用,而委托的绑定可以在蓝图中进行。
    下图为绑定委托,同时也是调用函数的参数。我们在DynDelTestFunc中对其调用。
    绑定委托
    典型案例就是SetTimerbyEvent蓝图结点,就是当时间截止时,调用绑定的委托。
    SetTimerbyEvent

  4. 动态多播委托: 这个更容易理解,它就是蓝图中的事件调度器(EventDispatcher),可以用其在C++和蓝图中绑定和调用委托。

事件

事件后续补充

  • 12
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
UE4中,您可以使用单播委托(Unicast Delegate)来实现事件的触发和处理。单播委托允许将一个或多个方法注册为事件的处理程序,并且可以使用payload参数传递数据。 以下是在UE4中使用单播委托和payload参数的示例: 1. 在您的类声明中定义委托类型和委托实例。例如: ```cpp DECLARE_DELEGATE_OneParam(FMyDelegate, const FString&); FMyDelegate MyDelegate; ``` 2. 在需要触发事件的地方,调用委托实例并传递payload参数。例如: ```cpp FString Payload = "Hello, World!"; MyDelegate.Execute(Payload); ``` 3. 在其他地方注册方法作为事件的处理程序,并定义方法的签名与委托类型一致。例如: ```cpp void MyClass::MyMethod(const FString& Payload) { UE_LOG(LogTemp, Warning, TEXT("MyMethod executed with payload: %s"), *Payload); } // 注册方法作为处理程序 MyDelegate.BindUObject(this, &MyClass::MyMethod); ``` 在上面的示例中,我们声明了FMyDelegate作为委托类型,并创建了一个委托实例MyDelegate。然后,在需要触发事件的地方,我们调用MyDelegate的Execute方法,并传递Payload参数。 在另一个类(例如MyClass)中,我们定义了一个名为MyMethod的方法,并使用BindUObject将其注册为处理程序。当事件触发时,MyMethod方法将被执行,并且可以访问传递的payload参数。 请注意,上述示例中的代码仅为演示目的,实际使用时您需要根据您的需求和代码结构进行适当的修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值