UE5 C++(十二)— 委托(代理)、多播委托

发布时间:2024年01月05日

介绍

这个官网上有很详细介绍,这里介绍几个点

定义

委托 是一种泛型但类型安全的方式,可在C++对象上调用成员函数。可使用委托动态绑定到任意对象的成员函数,之后在该对象上调用函数,即使调用程序不知对象类型也可进行操作。复制委托对象很安全。你也可以利用值传递委托,但这样操作需要在堆上分配内存,因此通常并不推荐。请尽量通过引用传递委托

声明委托

在这里插入图片描述

UDELEGATE(BlueprintAuthorityOnly)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FInstigatedAnyDamageSignature, float, Damage, const UDamageType*, DamageType, AActor*, DamagedActor, AActor*, DamageCauser);

绑定委托

在这里插入图片描述

MyDelegate.BindRaw( &MyFunction, true, 20 );

执行委托

在这里插入图片描述

WriteToLogDelegate.Execute(TEXT("Delegates are great!"));

单播委托

单播委托 只能绑定一个函数

创建一个C++类 MyDelegateActor

MyDelegateActor.h


#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyDelegateActor.generated.h"

DECLARE_DELEGATE(NoParamDelegate);//声明一个无参委托
DECLARE_DELEGATE_OneParam(OneParamDelegate, int32);//声明一个有一个int32参数的委托
DECLARE_DELEGATE_TwoParams(TwoParamsDelegate, int32, FString);//声明一个有一个int32参数和一个FString参数的委托
DECLARE_DELEGATE_RetVal(int32, RetValDelegate);//声明一个有返回值的委托

UCLASS()
class DEMO_API AMyDelegateActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AMyDelegateActor();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	NoParamDelegate NoParamDelegate;//声明一个无参委托
	OneParamDelegate OneParamDelegate;//声明一个有一个int32参数的委托
	TwoParamsDelegate TwoParamsDelegate;//声明一个有一个int32参数和一个FString参数的委托
	RetValDelegate RetValDelegate;//声明一个有返回值的委托

	void NoParamDelegateFunc();//无参委托函数
	void OneParamDelegateFunc(int32 Param);//有一个int32参数的委托函数
	void TwoParamsDelegateFunc(int32 Param1, FString Param2);//有一个int32参数和一个FString参数的委托函数
	int32 RetValDelegateFunc();//有返回值的委托函数

};

MyDelegateActor.cpp


#include "MyDelegateActor.h"

// Sets default values
AMyDelegateActor::AMyDelegateActor()
{
	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	NoParamDelegate.BindUObject(this, &AMyDelegateActor::NoParamDelegateFunc);	   // 绑定无参委托函数
	OneParamDelegate.BindUObject(this, &AMyDelegateActor::OneParamDelegateFunc);   // 绑定有一个int32参数的委托函数
	TwoParamsDelegate.BindUObject(this, &AMyDelegateActor::TwoParamsDelegateFunc); // 绑定有一个int32参数和一个FString参数的委托函数
	RetValDelegate.BindUObject(this, &AMyDelegateActor::RetValDelegateFunc);	   // 绑定有返回值的委托函数
}

// Called when the game starts or when spawned
void AMyDelegateActor::BeginPlay()
{
	Super::BeginPlay();
	NoParamDelegate.Execute(); // 执行无参委托函数
	OneParamDelegate.Execute(1); // 执行有一个int32参数的委托函数
	TwoParamsDelegate.Execute(1, TEXT("TwoParamsDelegate")); // 执行有一个int32参数和一个FString参数的委托函数
	int32 RetVal = RetValDelegate.Execute(); // 执行有返回值的委托函数
	UE_LOG(LogTemp, Warning, TEXT("RetVal:%d"), RetVal);
	
}

// Called every frame
void AMyDelegateActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}
void AMyDelegateActor::NoParamDelegateFunc()
{
	UE_LOG(LogTemp, Warning, TEXT("NoParamDelegateFunc"));
}
void AMyDelegateActor::OneParamDelegateFunc(int32 Param)
{
	UE_LOG(LogTemp, Warning, TEXT("OneParamDelegateFunc Param:%d"), Param);
}
void AMyDelegateActor::TwoParamsDelegateFunc(int32 Param1, FString Param2)
{
	UE_LOG(LogTemp, Warning, TEXT("TwoParamsDelegateFunc Param1:%d Param2:%s"), Param1, *Param2);
}
int32 AMyDelegateActor::RetValDelegateFunc()
{
	UE_LOG(LogTemp, Warning, TEXT("RetValDelegateFunc"));
	return 1;
}

然后把C++类 MyDelegateActor 拖到场景中,运行
在这里插入图片描述
在这里插入图片描述

多播委托

多播委托(代理) 可以绑定绑定多个函数

创建一个C++类 MyDelegateActor

MyDelegateActor.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyDelegateActor.generated.h"

// 多播委托代理
DECLARE_MULTICAST_DELEGATE(NoParamMulticastDelegate);							  // 声明一个无参多播委托
DECLARE_MULTICAST_DELEGATE_OneParam(OneParamMulticastDelegate, int32);			  // 声明一个有一个int32参数的多播委托
DECLARE_MULTICAST_DELEGATE_TwoParams(TwoParamsMulticastDelegate, int32, FString); // 声明一个有一个int32参数和一个FString参数的多播委托

UCLASS()
class DEMO_API AMyDelegateActor : public AActor
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	AMyDelegateActor();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	/*****     多播委托代理         ******/
	NoParamMulticastDelegate NoParamMulticastDelegate;	 // 声明一个无参多播委托
	OneParamMulticastDelegate OneParamMulticastDelegate;	 // 声明一个有一个int32参数的多播委托
	TwoParamsMulticastDelegate TwoParamsMulticastDelegate; // 声明一个有一个int32参数和一个FString参数的多播委托
	void NoParamMulticastDelegateFunc();					 // 无参多播委托函数
	void NoParamMulticastDelegateFunc2();
	void OneParamMulticastDelegateFunc(int32 Param);		 // 有一个int32参数的多播委托函数
	void OneParamMulticastDelegateFunc2(int32 Param);
	void TwoParamsMulticastDelegateFunc(int32 Param1, FString Param2); // 有一个int32参数和一个FString参数的多播委托函数
	void TwoParamsMulticastDelegateFunc2(int32 Param1, FString Param2); 
	
};

MyDelegateActor.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "MyDelegateActor.h"

// Sets default values
AMyDelegateActor::AMyDelegateActor()
{
	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	/*****     多播委托代理         ******/
	NoParamMulticastDelegate.AddUObject(this, &AMyDelegateActor::NoParamMulticastDelegateFunc); // 绑定无参多播委托函数
	NoParamMulticastDelegate.AddUObject(this, &AMyDelegateActor::NoParamMulticastDelegateFunc2);
	OneParamMulticastDelegate.AddUObject(this, &AMyDelegateActor::OneParamMulticastDelegateFunc); // 绑定有一个int32参数的多播委托函数
	OneParamMulticastDelegate.AddUObject(this, &AMyDelegateActor::OneParamMulticastDelegateFunc2);
	TwoParamsMulticastDelegate.AddUObject(this, &AMyDelegateActor::TwoParamsMulticastDelegateFunc); // 绑定有一个int32参数和一个FString参数的多播委托函数
	TwoParamsMulticastDelegate.AddUObject(this, &AMyDelegateActor::TwoParamsMulticastDelegateFunc2);
}

// Called when the game starts or when spawned
void AMyDelegateActor::BeginPlay()
{
	Super::BeginPlay();

	/*****     多播委托代理         ******/
	NoParamMulticastDelegate.Broadcast();								// 执行无参多播委托函数
	OneParamMulticastDelegate.Broadcast(1);								// 执行有一个int32参数的多播委托函数
	TwoParamsMulticastDelegate.Broadcast(1, TEXT("TwoParamsDelegate")); // 执行有一个int32参数和一个FString参数的多播委托函数
}

// Called every frame
void AMyDelegateActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

/*****     多播委托代理         ******/
void AMyDelegateActor::NoParamMulticastDelegateFunc()
{
	UE_LOG(LogTemp, Warning, TEXT("NoParamMulticastDelegateFunc"));
}
void AMyDelegateActor::NoParamMulticastDelegateFunc2()
{
	UE_LOG(LogTemp, Warning, TEXT("NoParamMulticastDelegateFunc2"));
}
void AMyDelegateActor::OneParamMulticastDelegateFunc(int32 Param)
{
	UE_LOG(LogTemp, Warning, TEXT("OneParamMulticastDelegateFunc Param:%d"), Param);
}
void AMyDelegateActor::OneParamMulticastDelegateFunc2(int32 Param)
{
	UE_LOG(LogTemp, Warning, TEXT("OneParamMulticastDelegateFunc2 Param:%d"), Param);
}
void AMyDelegateActor::TwoParamsMulticastDelegateFunc(int32 Param1, FString Param2)
{
	UE_LOG(LogTemp, Warning, TEXT("TwoParamsMulticastDelegateFunc Param1:%d Param2:%s"), Param1, *Param2);
}
void AMyDelegateActor::TwoParamsMulticastDelegateFunc2(int32 Param1, FString Param2)
{
	UE_LOG(LogTemp, Warning, TEXT("TwoParamsMulticastDelegateFunc2 Param1:%d Param2:%s"), Param1, *Param2);
}

打印日志
在这里插入图片描述

动态多播代理

动态多播委托代理 区别在于可以暴露给蓝图,在蓝图中进行事件绑定, 一定要是F开头
还有就是参数和参数名一定要配合使用

创建一个C++类 MyDelegateActor

MyDelegateActor.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyDelegateActor.generated.h"

// 动态多播委托代理 区别在于可以暴露给蓝图,在蓝图中进行事件绑定, 一定要是F开头
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FNoParamDynamicMulticastDelegate);												  // 声明一个无参多播委托
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOneParamDynamicMulticastDelegate, FString, ParamStr);					  // 声明一个有一个int32参数的多播委托
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FTwoParamsDynamicMulticastDelegate, int32, ParamInt, FString, ParamStr); // 声明一个有一个int32参数和一个FString参数的多播委托

UCLASS()
class DEMO_API AMyDelegateActor : public AActor
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	AMyDelegateActor();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:
	// Called every frame
	virtual void Tick(float DeltaTime) override;
	/*****     动态多播委托代理         ******/
	UPROPERTY(BlueprintAssignable, Category = "MyDelegate")
	FNoParamDynamicMulticastDelegate NoParamDynamicMulticastDelegate; // 声明一个无参多播委托
	UPROPERTY(BlueprintAssignable, Category = "MyDelegate")
	FOneParamDynamicMulticastDelegate OneParamDynamicMulticastDelegate; // 声明一个有一个int32参数的多播委托
	UPROPERTY(BlueprintAssignable, Category = "MyDelegate")
	FTwoParamsDynamicMulticastDelegate TwoParamsDynamicMulticastDelegate; // 声明一个有一个int32参数和一个FString参数的多播委托
};

MyDelegateActor.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "MyDelegateActor.h"

// Sets default values
AMyDelegateActor::AMyDelegateActor()
{
	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
}

// Called when the game starts or when spawned
void AMyDelegateActor::BeginPlay()
{
	Super::BeginPlay();

	/*****     执行动态多播委托代理         ******/
	NoParamDynamicMulticastDelegate.Broadcast();
	OneParamDynamicMulticastDelegate.Broadcast(TEXT("OneParamsDelegate"));
	TwoParamsDynamicMulticastDelegate.Broadcast(1, TEXT("TwoParamsDelegate"));
}

// Called every frame
void AMyDelegateActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

编译之后,创建蓝图类BP_MyDelegateActor

在蓝图中实现

在这里插入图片描述
打印日志
在这里插入图片描述
在这里插入图片描述

文章来源:https://blog.csdn.net/qq_40120946/article/details/135402133
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。