【转载】UE4 中的代理(Delegate)使用总结

542 阅读3分钟

原文链接:UE4 中的代理(Delegate)使用总结

前言

刚接触到 UE4 中的代理(Delegate)是一头雾水,经过不断尝试,现在终于稍微摸清它的脉络。UE4 Editor 中有大量的 Delegate 使用代码,而在实际项目中,我们可能要需要delegate来完成我们自己的消息机制。

概念

Delegate 跟 JavaScript中 的 Event,以及 MFC 中 Message,概念上是一样的,是 UE4 中一种自定义的消息机制。基本上可以将 delegateevent 相等同。

使用过程

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 函数等。

  1. BindRaw: 原生 C++
  2. BindUObjectUObjectUFunction 函数
  3. BindStatic: 静态函数