UE4中的委托和事件

本文介绍了UE4中的委托和事件,包括单播、多播、动态单播和动态多播委托的使用,以及在蓝图中的创建和应用。详细阐述了委托的声明、创建、执行和绑定过程,同时提供了各种委托类型的快速参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍

官方文档介绍

  • 委托本身是一种特殊对象
  • 委托可绑定任意对象的函数
  • 委托是一种观察者模式,当委托执行时,通知所有绑定到这个委托的对象

定义委托类的宏可以在DelegateCombinations.h查看,这里只暂时只展示了无参数的宏。这些宏用于声明和定义一个委托类。

#define DECLARE_DELEGATE( DelegateName ) FUNC_DECLARE_DELEGATE( DelegateName, void )
#define DECLARE_MULTICAST_DELEGATE( DelegateName ) FUNC_DECLARE_MULTICAST_DELEGATE( DelegateName, void )
#define DECLARE_EVENT( OwningType, EventName ) FUNC_DECLARE_EVENT( OwningType, EventName, void )
#define DECLARE_DYNAMIC_DELEGATE( DelegateName ) BODY_MACRO_COMBINE(CURRENT_FILE_ID,_,__LINE__,_DELEGATE) FUNC_DECLARE_DYNAMIC_DELEGATE( FWeakObjectPtr, DelegateName, DelegateName##_DelegateWrapper, , FUNC_CONCAT( *this ), void )
#define DECLARE_DYNAMIC_MULTICAST_DELEGATE( DelegateName ) BODY_MACRO_COMBINE(CURRENT_FILE_ID,_,__LINE__,_DELEGATE) FUNC_DECLARE_DYNAMIC_MULTICAST_DELEGATE( FWeakObjectPtr, DelegateName, DelegateName##_DelegateWrapper, , FUNC_CONCAT( *this ), void )
#define DECLARE_DELEGATE_RetVal( ReturnValueType, DelegateName ) FUNC_DECLARE_DELEGATE( DelegateName, ReturnValueType )
#define DECLARE_DYNAMIC_DELEGATE_RetVal( ReturnValueType, DelegateName ) BODY_MACRO_COMBINE(CURRENT_FILE_ID,_,__LINE__,_DELEGATE) FUNC_DECLARE_DYNAMIC_DELEGATE_RETVAL( FWeakObjectPtr, DelegateName, DelegateName##_DelegateWrapper, ReturnValueType, , FUNC_CONCAT( *this ), ReturnValueType )

从上往下一次是:

  • 单播委托:只能绑定一个函数
  • 多播委托:可绑定多个函数
  • 事件:特殊的多播委托,只能在指定类中触发
  • 动态单播委托:只能绑定一个函数,可暴露给蓝图使用
  • 动态多播委托:能绑定多个函数,可暴露给蓝图使用
  • 单播委托_带返回值:以上只能绑定void函数,这个可绑定带返回值的函数,并可使用返回值
  • 动态单播委托_带返回值:同上,可暴露给蓝图使用

可以看到关键词的意义:
单播:只能绑定一个函数
多播:可绑定多个函数
动态:可给蓝图使用
带返回值:可绑定带返回值的函数,并可获取返回值(所以也只支持单播)
事件:类限定的多播

翻看Actor.h会发现其使用的是稀疏动态多播代理,如下。

DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam(FActorDestroyedSignature, AActor, OnDestroyed, AActor*, DestroyedActor );
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams(FActorEndPlaySignature, AActor, OnEndPlay, AActor*, Actor , EEndPlayReason::Type, EndPlayReason);

源码中的解释:

稀疏的委托可以用于不经常绑定的委托,以便对象仅使用1个字节的存储空间,而不用承担委托调用列表的全部开销。 从委托中调用,添加,删除等的成本高于直接使用委托的成本,因此应在节省内存的好处与期望绑定委托的频率之间进行权衡。

委托的使用

委托的使用可分为4个步骤:

  • 声明委托(委托签名):使用宏声明和定义一个委托类,表明委托可接受的函数签名
  • 创建委托:在需要执行委托的类中声明一个委托成员变量
  • 执行委托:执行委托,会触发绑定的函数
  • 绑定委托:将委托执行时触发的对象成员函数绑定到这个委托上

以上是按照开发时写代码的顺序,实际运行时是绑定在前、执行在后。

示例:

// 1.声明和定义一个委托类
DECLARE_DELEGATE(FMyDelegate);

class  FMyObject
{
   
public:
	void MyFunction();
	
	// 2.创建一个委托成员变量
	FMyDelegate MyDeleage;
};

void FMyObject::MyFunction()
{
   
	// 3.执行委托
	MyDelegate.
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值