Delegate in UnrealEngine ——虚幻四中的委托

时间:2022-04-20 04:01:59

@ CloudGuan
@ Copyright 2016 Cloud Guan, Inc. All Rights Reserved.

Delegates System In Unreal Engine

What is delegates in Unreal Engine?And How use it?

Delegates allow you to call member functions on C++ objects in a generic, yet type-safe way. Using delegates, you can dynamically bind to a member function of an arbitrary object, then call functions on the object, even if the caller does not know the object’s type.
代理机制允许你可以类型安全的使用C++类的成员函数,还可以自动的绑定成员函数到任意的变量上,然后通过这个变量来调用,我们这个变量甚至不需要知道它的类型。
It is perfectly safe to copy delegate objects. Delegates can be passed around by value but this is generally not recommended since they do have to allocate memory on the heap. You should always pass delegates by reference when possible.
拷贝代理变量是完全安全的,代理可以使用值传递,但是因为他们会在堆上分配内存的原因,所以不建议这样做。最好是通过引用传递的方式来传递这个值
Both single-cast and multi-cast delegates are supported, as well as “dynamic” delegates which can be safely serialized to disk.
代理支持单播和广播,自动的代理会更加的安全在序列化到磁盘的时候

Type of Delegate

这是可以用于普通类型和函数的代理,没有特别要求使用UCALSS标记宏标记的类,基本声明方式如下表所示:

FuntionType Declear Delegate
void Function() DECLEAR_DELEGATE(Name)
void Fucntion(param1) DECLEAR_DELEGATE_OneParam(Name,paramType,paramType)
void Function(Param1,Param2,…) DECLARE_DELEGATE_Params( DelegateName, Param1Type, Param2Type, … )
RetVal Function() DECLARE_DELEGATE_RetVal( RetValType, DelegateName)

但是上面的宏不能被蓝图使用,这个时候我们需要使用到新的一种代理,dynamic delegate同时声明别的代理的宏定义的方式如下
- DECLARE_MULTICAST_DELEGATE(DelegateName,ParamType,ParamName)
- DECLARE_DYNAMIC_DELEGATE
- DECLARE_MULTICAST_DYNAMIC_DELEGATE
注意这里的声明方式有点不同两种代理方式,而且参数如果是自定义的类的话,也要被UNREALBUILDTOOLS的宏进行标记,而且这里不止要声明参数类型和还要声明参数名字

//另外这里补充一个代理的高级用法,在代理参数不够的时候,我们可以把额外的参数通过绑定代理的时候给传递进去

DCLEAR_DELEGATE(CloudGuanTextDelegate)

class CloudGuanText
{
public:
static CloudGuanTextDelegate mydelegate;

void cloudaguantext(FString Name);
};
//cpp
....
FString aaa=TEXT("aaaaaaa");
CloudGuanText cloudguan=new CloudGuanText();
cloudguan.mydelegate.BindRaw(this,&CloudGuanText::cloudaguantext,aaa);

Bind Delegates

函数 使用描述
Bind() Binds to an existing delegate object.绑定到现有的委托对象?
BindStatic 绑定原生的全局C++函数的指针到一个Delegate
BindRaw() 绑定一个C++的指针到代理上,原生的指针没有使用任何的智能指针相关的特性,所以他是不安全的
BindSP() 绑定一个基于sharedPoint的成员函数代理,建议使用 ExecuteIfBound()调用
BindUOjecr 绑定一个基于UObject的成员函数到代理,UObject delegate持有到这个UObject的弱引用
UnBind() 解绑定

绑定代理是把这个代理需要执行的函数绑定到代理,当需要执行的实行调用Execute 或者ExecuteIfBound
下面是各个绑定方式的参数:

/**
* Binds an arbitrary function that will be called to generate this attribute's value on demand. After
* binding, the attribute will no longer have a value that can be accessed directly, and instead the bound
* function will always be called to generate the value.
*
* @param InGetter The delegate object with your function binding
*/

//这里的意思是我们需要传递的参数是一个代理的引用就好
void Bind( const FGetter& InGetter )
{
bIsSet = true;
Getter = InGetter;
}
/**
* Binds a raw C++ pointer global function delegate
* 绑定的参数是一个函数的名字,这个函数要是是个全局函数
*/

inline void BindStatic( typename FStaticDelegate::FFuncPtr InFunc )
{
*this = CreateStatic( InFunc );
}

//这里是绑定一个传统c++类的指针,需要包含类的实列的指针以及成员函数,当然还有参数
inline void BindRaw( UserClass* InUserObject, typename TRawMethodDelegate_ThreeVars_Const< UserClass, PAYLOAD_TEMPLATE_LIST_ThreeVars >::FMethodPtr InFunc, PAYLOAD_TEMPLATE_ARGS_ThreeVars )
{
*this = CreateRaw( InUserObject, InFunc, PAYLOAD_TEMPLATE_PASSIN_ThreeVars );
}
//绑定一个基于智能指针的类的成员函数,同样需要这个参数和类的实例的指针
inline void BindSP( UserClass* InUserObject, typename TSPMethodDelegate_ThreeVars_Const< UserClass, PAYLOAD_TEMPLATE_LIST_ThreeVars >::FMethodPtr InFunc, PAYLOAD_TEMPLATE_ARGS_ThreeVars )
{
*this = CreateSP( InUserObject, InFunc, PAYLOAD_TEMPLATE_PASSIN_ThreeVars );
}
//绑定一个基于UObject的类的成员函数,需要的参数是这个类的实例的指针和函数指针
inline void BindUObject( UserClass* InUserObject, typename TUObjectMethodDelegate_FourVars_Const< UserClass, PAYLOAD_TEMPLATE_LIST_FourVars >::FMethodPtr InFunc, PAYLOAD_TEMPLATE_ARGS_FourVars )
{
*this = CreateUObject( InUserObject, InFunc, PAYLOAD_TEMPLATE_PASSIN_FourVars );
}

这里绑定参数形式是this,加上函数指针,原因是c++调用函数的原理,之后补充。