前言
刚接触到 UE4 中的代理(Delegate)是一头雾水,经过不断尝试,现在终于稍微摸清它的脉络。UE4 Editor 中有大量的 Delegate 使用代码,而在实际项目中,我们可能要需要delegate来完成我们自己的消息机制。
概念
Delegate 跟 JavaScript中 的 Event,以及 MFC 中 Message,概念上是一样的,是 UE4 中一种自定义的消息机制。基本上可以将 delegate
与 event
相等同。
使用过程
1. 申明一个代理(消息)类型
DECLARE_DELEGATE(FStandardDelegateSignature)
FStandardDelegateSignature
就是我们自己定义代理类型,可以将 FStandardDelegateSignature
看成使用 UE 宏 DECLARE_DELEGATE
声明的一个类(Class)
2. 定义一个代理(消息)
FStandardDelegateSignature MyStandardDelegate;
MyStandardDelegate
就是我们自己定义的一个代理,可以看成 FStandardDelegateSignature
的一个实例 Instance
3. 绑定响应函数
MyStandardDelegate.BindUObject(this, &ADelegateListener::EnableLight)
绑定响应函数就是定义代理(消息)被触发时的响应函数,跟 Javascript 中的 callback 函数原理是一样的。
4. 触发代理(消息)
MyStandardDelegate.ExeIfBound();
前面三步已经完成消息的注册,这一步就可以触发代理,然后执行代理定义好的响应函数,完成整个消息处理流程。
5. 解除绑定响应函数
MyStandardDelegate.Unbind();
如果后续不再需要响应函数,可以及时取消代理与响应函数的绑定。
代理分类
第一种分类:
代理按绑定响应函数的个数分成:Standard delegate(标准代理,或者叫做单播代理)和 MultiCast delegate(多播代理)。他们之间区别非常简单,
MultiCast
支持绑定多个响应函数,Standard delegate 只能有一个响应函数,也就是说 MultiCast delegate 跟广播的概念是一样的,有群发的效果。
Multicast delegate 的使用
DECLARE_*MULTICAST*_DELEGATE(FMulticastDelegateSignature)
FMultiDelegateSignature MyMulticastDelegate
MyMulticastDelegate.AddUObject(this, &ResponseFunction)
MyMulticastDelegate.Broadcast()
MyMulticastDelegate.RemoveAll()
第二种分类:
按是否可以在蓝图中调用来分类:标准(静态)代理与动态代理(Dynamic)
动态代理与标准代理之间区别:动态代理 支持序列化,因此可以在蓝图中使用,而标准的却不能。
UE4 中可申明的代理类型
前面提到代理分类,第一种分类和第二种分类是可以组合的。所以,你经常会听到 动态多播代理 这种叫法,也就是长成这样的定义代理的宏:
DECLARE_DYNAMIC_MULTICAST_DELEGATE
代理参数及其返回值
代理中的参数及其返回值,其实是给响应函数使用的,也就是 将一个参数传给响应函数,并从响应函数中返回值给代理 。这个过程发生在代理执行(Execute
)的时候。
DECLARE_DELEGATE_RetVal_OneParam( RetValType, DelegateName, Param1Type )
其中 RetValType
为响应函数返回值的类型,Param1Type
是响应函数第一个参数的类型。
由于 UE4 中代理都是通过宏来实现的,在使用的时候也有一个比较 2 的问题。如果你突然想为你的 delegate 响应函数添加一个参数,你必须要重新使用新的宏,可能会长成这样:
DECLARE_DELEGATE_RetVal_TwoParam( RetValType, DelegateName, Param1Type, Param1Type )
代理绑定响应函数的类型
代理可以绑定多种类型的函数,原生 C++ 函数,UFunction
函数等。
BindRaw
: 原生 C++BindUObject
:UObject
的UFunction
函数BindStatic
: 静态函数