8- UE4代理(单播代理)

8. UE4代理(单播代理)

代理相当于一个函数指针的类型,或者是Qt中的信号的类型,用于间接调用函数。

1. 代理类型的声明

代理在被使用以创建变量之前应该被声明:

  • 返回值:是否存在返回值,以及返回值的类型

  • 参数:有几个参数,以及相应参数类型

  • 命名:代理的名字

// 单播代理
DECLARE_DELEGATE(FTestDelegateNoParam); //无参无返回值代理(命名最好规范:F+代理名+Delegate+参数数量)
DECLARE_DELEGATE_TwoParams(FTestDelegateTwoParams, float, const FString&); //双参数,无返回值
DECLARE_DELEGATE_RetVal_TwoParams(int32, FTestDelegateTwoParamsRetVal, float, const FString&); //双参数,有返回值

2. 代理的创建

2.1 绑定UObject类成员函数(BindUObject)

​ 代理被声明后,创建相应的代理对象,并绑定相应的函数:

class AMyActor : public AActor
{
//...

FTestDelegateTwoParamsRetVal DelegateTwoParamsRetVal; //创建一个代理
int32 Func(float a, const FString& s); // 被绑定的函数
};

int32 AMyActor::Func(float a, const FString& s)
{
//...
}

void AMyActor::BeginPlay()
{
Super::BeginPlay();
DelegateTwoParamsRetVal.BindUObject(this, &AMyActor::Func);
}

2.2 绑定lambda表达式(BindLambda)

​ 下面演示了双参,带返回值的代理绑定Lambda表达式的情况:

DelegateTwoParamsRetVal.BindLambda([](float a, const FString& s)->int32{ return 1;});

2.3 绑定原生的C++类成员函数(BindRaw)

class FTestA
{
public:
int32 Func(float a, const FString& s)
{
//...
}
};

FTestA a;
DelegateTwoParamsRetVal.BindRaw(&a, &FTestA::Func); //绑定原生C++类

2.4 绑定共享指针(BindSP)

class FTestA
{
public:
int32 Func(float a, const FString& s)
{
//...
}
};

TSharedPtr<FTestA> a1 = MakeShareable(new FTestA);
DelegateTwoParamsRetVal.BindSP(a1.ToSharedRef(), &FTestA::Func);

2.5 绑定静态函数(BindStatic)

class FTestA
{
public:
static int32 Func(float a, const FString& s)
{
//...
}
};

DelegateTwoParamsRetVal.BindStatic(Func);

2.6 绑定线程安全的共享指针(BindThreadSafeSP)

class FTestA
{
public:
int32 Func(float a, const FString& s)
{
//...
}
};

TSharedPtr<FTestA, ESPMode::ThreadSafe> a2 = MakeShareable(new FTestA);
DelegateTwoParamsRetVal.BindThreadSafeSP(a2.ToSharedRef(), &FTestA::Func);

2.7 通过函数名绑定(反射)(UFunction)

class AMyActor : public AActor
{
//...

FTestDelegateTwoParamsRetVal DelegateTwoParamsRetVal; //创建一个代理

UFUNCTION() // 设置为U Funcion
int32 Func(float a, const FString& s); // 被绑定的函数
};

int32 AMyActor::Func(float a, const FString& s)
{
//...
}

void AMyActor::BeginPlay()
{
Super::BeginPlay();
DelegateTwoParamsRetVal.BindUFunction(this, FName("Func"));
}

3. 调用代理绑定的对象(Execute)

​ 使用Execute调用绑定的对象:

if(DelegateTwoParamsRetVal.IsBound())
{
DelegateTwoParamsRetVal.Execute(23, "Hello Delegate");
}

无参代理的新方法

DECLARE_DELEGATE.ExecuteIfBound();	//无参数执行

4. 解绑定(UnBind)

​ 一般在临时对象身上,临时对象即将离开生命周期,进行代理的解除绑定:

DelegateTwoParamsRetVal.UnBind();