【UE】UEC++委托代理
一、委托的声明与定义
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "DelegateGameMode.generated.h"
//
// Declare DECLARE_DELEGATE
//
DECLARE_DELEGATE(FDeclareDelegate_00);
DECLARE_DELEGATE_OneParam(FDeclareDelegate_01, bool);
DECLARE_DELEGATE_TwoParams(FDeclareDelegate_02, bool, int32);
DECLARE_DELEGATE_RetVal(bool, FDeclareDelegate_03);
DECLARE_DELEGATE_RetVal_OneParam(bool, FDeclareDelegate_04, bool);
//
// Declare DECLARE_MULTICAST_DELEGATE
//
DECLARE_MULTICAST_DELEGATE(FDeclareMulticastDelegate_00);
DECLARE_MULTICAST_DELEGATE_OneParam(FDeclareMulticastDelegate_01, int32);
//
// Declare DECLARE_DYNAMIC_DELEGATE
//
DECLARE_DYNAMIC_DELEGATE(FDeclareDynamicDelegate_00);
DECLARE_DYNAMIC_DELEGATE_OneParam(FDeclareDynamicDelegate_01, int32, iValue);
DECLARE_DYNAMIC_DELEGATE_RetVal(bool, FDeclareDynamicDelegate_02);
DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(bool, FDeclareDynamicDelegate_03, int32, iValue);
//
// Declare DECLARE_DYNAMIC_MULTICAST_DELEGATE
//
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDeclareDynamicMulticastDelegate_00);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDeclareDynamicMulticastDelegate_01, int32, iValue);
UCLASS()
class DELEGATE_API ADelegateGameMode : public AGameModeBase
{
	GENERATED_BODY()
public:
	//
	// Define DECLARE_DELEGATE
	//
	FDeclareDelegate_00 DeclareDelegate_00;
	FDeclareDelegate_01 DeclareDelegate_01;
	FDeclareDelegate_02 DeclareDelegate_02;
	FDeclareDelegate_03 DeclareDelegate_03;
	FDeclareDelegate_04 DeclareDelegate_04;
	//
	// Define DECLARE_MULTICAST_DELEGATE
	//
	FDeclareMulticastDelegate_00 DeclareMulticastDelegate_00;
	FDeclareMulticastDelegate_01 DeclareMulticastDelegate_01;
	//
	// Define DECLARE_DYNAMIC_DELEGATE
	//
	FDeclareDynamicDelegate_00 DeclareDynamicDelegate_00;
	FDeclareDynamicDelegate_01 DeclareDynamicDelegate_01;
	FDeclareDynamicDelegate_02 DeclareDynamicDelegate_02;
	FDeclareDynamicDelegate_03 DeclareDynamicDelegate_03;
	//
	// Define DECLARE_DYNAMIC_MULTICAST_DELEGATE
	//
	FDeclareDynamicMulticastDelegate_00 DeclareDynamicMulticastDelegate_00;
	FDeclareDynamicMulticastDelegate_01 DeclareDynamicMulticastDelegate_01;
};
 
二、单播绑定与解绑
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DeclareDelegate.generated.h"
UCLASS()
class DELEGATE_API ADeclareDelegate : public AActor
{
	GENERATED_BODY()
public:	
	ADeclareDelegate();
	virtual void Tick(float DeltaTime) override;
protected:
	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
public:
	UFUNCTION()
	void BindDelegate();
	UFUNCTION()
	void UnBindDelegate();
	
	UFUNCTION()
	void FunNoParam();
	UFUNCTION()
	void FunOneParam(bool bValue);
	UFUNCTION()
	void FunTwoParam(bool bValue, int32 iValue);
	UFUNCTION()
	bool FunRetValNoParam();
	UFUNCTION()
	bool FunRetValOneParam(bool bValue);
};
 
#include "DeclareDelegate.h"
#include "Delegate/GameMode/DelegateGameMode.h"
#include "Kismet/GameplayStatics.h"
ADeclareDelegate::ADeclareDelegate()
{
	PrimaryActorTick.bCanEverTick = false;
}
void ADeclareDelegate::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}
void ADeclareDelegate::BeginPlay()
{
	Super::BeginPlay();
	BindDelegate();
}
void ADeclareDelegate::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);
	UnBindDelegate();
}
void ADeclareDelegate::BindDelegate()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDelegateActor::BindDegelate"))
	if(GetWorld())
	{
		ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
		DelegateGameMode->DeclareDelegate_00.BindUObject(this, &ThisClass::FunNoParam);
		DelegateGameMode->DeclareDelegate_01.BindUFunction(this, "FunOneParam");
		DelegateGameMode->DeclareDelegate_02.BindUObject(this, &ThisClass::FunTwoParam);
		DelegateGameMode->DeclareDelegate_03.BindUObject(this, &ThisClass::FunRetValNoParam);
		DelegateGameMode->DeclareDelegate_04.BindUFunction(this, "FunRetValOneParam");
	}
}
void ADeclareDelegate::UnBindDelegate()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDelegateActor::UnBindDegelate"))
	if(GetWorld())
	{
		ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
		DelegateGameMode->DeclareDelegate_00.Unbind();
		DelegateGameMode->DeclareDelegate_01.Unbind();
		DelegateGameMode->DeclareDelegate_02.Unbind();
		DelegateGameMode->DeclareDelegate_03.Unbind();
		DelegateGameMode->DeclareDelegate_04.Unbind();
	}
}
void ADeclareDelegate::FunNoParam()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDelegateActor::FunNoParam"))
}
void ADeclareDelegate::FunOneParam(bool bValue)
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDelegateActor::FunOneParam"))
}
void ADeclareDelegate::FunTwoParam(bool bValue, int32 iValue)
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDelegateActor::FunTwoParam"))
}
bool ADeclareDelegate::FunRetValNoParam()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDelegateActor::FunRetValNoParam"))
	return false;
}
bool ADeclareDelegate::FunRetValOneParam(bool bValue)
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDelegateActor::FunRetValOneParam"))
	return bValue;
} 
三、多播绑定与解绑
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DeclareMulticastDelegate.generated.h"
UCLASS()
class DELEGATE_API ADeclareMulticastDelegate : public AActor
{
	GENERATED_BODY()
	
public:	
	ADeclareMulticastDelegate();
	virtual void Tick(float DeltaTime) override;
protected:
	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
public:
	UFUNCTION()
	void BindDelegate();
	UFUNCTION()
	void UnBindDelegate();
		
	UFUNCTION()
	void FunNoParam_One();
	UFUNCTION()
	void FunNoParam_Two();
	UFUNCTION()
	void FunOneParam_One(int32 iValue);
	UFUNCTION()
	void FunOneParam_Two(int32 iValue);
private:
	FDelegateHandle DelegateHandle;
	TArray<FDelegateHandle> DelegateHandles;
}; 
#include "DeclareMulticastDelegate.h"
#include "Delegate/GameMode/DelegateGameMode.h"
#include "Kismet/GameplayStatics.h"
ADeclareMulticastDelegate::ADeclareMulticastDelegate()
{
	PrimaryActorTick.bCanEverTick = false;
}
void ADeclareMulticastDelegate::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}
void ADeclareMulticastDelegate::BeginPlay()
{
	Super::BeginPlay();
	BindDelegate();
}
void ADeclareMulticastDelegate::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);
	UnBindDelegate();
}
void ADeclareMulticastDelegate::BindDelegate()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareMulticastDelegateActor::BindDegelate"))
	if(GetWorld())
	{
		ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
		DelegateGameMode->DeclareMulticastDelegate_00.AddUObject(this, &ThisClass::FunNoParam_One);
		DelegateHandle = DelegateGameMode->DeclareMulticastDelegate_00.AddUFunction(this, "FunNoParam_Two");
		DelegateHandles.Add(DelegateGameMode->DeclareMulticastDelegate_01.AddUObject(this, &ThisClass::FunOneParam_One));
		DelegateHandles.Add(DelegateGameMode->DeclareMulticastDelegate_01.AddUFunction(this, "FunOneParam_Two"));
	}
}
void ADeclareMulticastDelegate::UnBindDelegate()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareMulticastDelegateActor::UnBindDelegate"))
	if(GetWorld())
	{
		ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
		DelegateGameMode->DeclareMulticastDelegate_00.RemoveAll(this);
		
		for(FDelegateHandle Handle : DelegateHandles)
		{
			DelegateGameMode->DeclareMulticastDelegate_01.Remove(Handle);
		}
	}
}
void ADeclareMulticastDelegate::FunNoParam_One()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareMulticastDelegateActor::FunNoParam_One"))
}
void ADeclareMulticastDelegate::FunNoParam_Two()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareMulticastDelegateActor::FunNoParam_Two"))
	
	if(GetWorld())
	{
		ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
		DelegateGameMode->DeclareMulticastDelegate_00.Remove(DelegateHandle);
	}
}
void ADeclareMulticastDelegate::FunOneParam_One(int32 iValue)
{
	UE_LOG(LogTemp,Log,TEXT("DeclareMulticastDelegateActor::FunOneParam_One"))
}
void ADeclareMulticastDelegate::FunOneParam_Two(int32 iValue)
{
	UE_LOG(LogTemp,Log,TEXT("DeclareMulticastDelegateActor::FunOneParam_Two"))
} 
四、动态单播绑定与解绑
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DeclareDynamicDelegate.generated.h"
UCLASS()
class DELEGATE_API ADeclareDynamicDelegate : public AActor
{
	GENERATED_BODY()
public:	
	ADeclareDynamicDelegate();
	virtual void Tick(float DeltaTime) override;
protected:
	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
public:	
	UFUNCTION()
	void BindDelegate();
	UFUNCTION()
	void UnBindDelegate();
	UFUNCTION()
	void FunNoParam();
	UFUNCTION()
	void FunOneParam(int32 iValue);
	UFUNCTION()
	bool FunRetValNoParam();
	UFUNCTION()
	bool FunRetValOneParam(int32 iValue);
};
 
#include "DeclareDynamicDelegate.h"
#include "Delegate/GameMode/DelegateGameMode.h"
#include "Kismet/GameplayStatics.h"
ADeclareDynamicDelegate::ADeclareDynamicDelegate()
{
	PrimaryActorTick.bCanEverTick = false;
}
void ADeclareDynamicDelegate::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}
void ADeclareDynamicDelegate::BeginPlay()
{
	Super::BeginPlay();
	BindDelegate();
}
void ADeclareDynamicDelegate::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);
	UnBindDelegate();
}
void ADeclareDynamicDelegate::BindDelegate()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicDelegate::BindDelegate"))
	if(GetWorld())
	{
		ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
		DelegateGameMode->DeclareDynamicDelegate_00.BindDynamic(this, &ThisClass::FunNoParam);
		DelegateGameMode->DeclareDynamicDelegate_01.BindUFunction(this, "FunOneParam");
		DelegateGameMode->DeclareDynamicDelegate_02.BindDynamic(this, &ThisClass::FunRetValNoParam);
		DelegateGameMode->DeclareDynamicDelegate_03.BindUFunction(this, "FunRetValOneParam");
	}
}
void ADeclareDynamicDelegate::UnBindDelegate()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicDelegate::UnBindDelegate"))
	if(GetWorld())
	{
		ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
		DelegateGameMode->DeclareDynamicDelegate_00.Clear();
		DelegateGameMode->DeclareDynamicDelegate_01.Unbind();
		DelegateGameMode->DeclareDynamicDelegate_02.Clear();
		DelegateGameMode->DeclareDynamicDelegate_03.Unbind();
	}
}
void ADeclareDynamicDelegate::FunNoParam()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicDelegate::FunNoParam"))
}
void ADeclareDynamicDelegate::FunOneParam(int32 iValue)
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicDelegate::FunOneParam"))
}
bool ADeclareDynamicDelegate::FunRetValNoParam()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicDelegate::FunRetValNoParam"))
	return false;
}
bool ADeclareDynamicDelegate::FunRetValOneParam(int32 iValue)
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicDelegate::FunRetValOneParam"))
	return false;
} 
五、动态多播绑定与解绑
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DeclareDynamicMulticastDelegate.generated.h"
UCLASS()
class DELEGATE_API ADeclareDynamicMulticastDelegate : public AActor
{
	GENERATED_BODY()
public:	
	ADeclareDynamicMulticastDelegate();
	virtual void Tick(float DeltaTime) override;
protected:
	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
public:
	UFUNCTION()
	void BindDelegate();
	UFUNCTION()
	void UnBindDelegate();
	
	UFUNCTION()
	void FunNoParam_One();
	UFUNCTION()
	void FunNoParam_Two();
	UFUNCTION()
	void FunOneParam_One(int32 iValue);
	UFUNCTION()
	void FunOneParam_Two(int32 iValue);
}; 
#include "DeclareDynamicMulticastDelegate.h"
#include "Delegate/GameMode/DelegateGameMode.h"
#include "Kismet/GameplayStatics.h"
ADeclareDynamicMulticastDelegate::ADeclareDynamicMulticastDelegate()
{
	PrimaryActorTick.bCanEverTick = false;
}
void ADeclareDynamicMulticastDelegate::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}
void ADeclareDynamicMulticastDelegate::BeginPlay()
{
	Super::BeginPlay();
	BindDelegate();
}
void ADeclareDynamicMulticastDelegate::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);
	UnBindDelegate();
}
void ADeclareDynamicMulticastDelegate::BindDelegate()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicMulticastDelegate::BindDelegate"))
	if(GetWorld())
	{
		ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
		DelegateGameMode->DeclareDynamicMulticastDelegate_00.AddDynamic(this, &ThisClass::FunNoParam_One);
		DelegateGameMode->DeclareDynamicMulticastDelegate_00.AddUniqueDynamic(this, &ThisClass::FunNoParam_Two);
		DelegateGameMode->DeclareDynamicMulticastDelegate_01.AddDynamic(this, &ThisClass::FunOneParam_One);
		DelegateGameMode->DeclareDynamicMulticastDelegate_01.AddUniqueDynamic(this, &ThisClass::FunOneParam_Two);
	}
}
void ADeclareDynamicMulticastDelegate::UnBindDelegate()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicMulticastDelegate::UnBindDelegate"))
	if(GetWorld())
	{
		ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
		DelegateGameMode->DeclareDynamicMulticastDelegate_00.Remove(this, "FunNoParam_One");
		DelegateGameMode->DeclareDynamicMulticastDelegate_00.RemoveDynamic(this, &ThisClass::FunNoParam_Two);
		DelegateGameMode->DeclareDynamicMulticastDelegate_01.RemoveAll(this);
	}
}
void ADeclareDynamicMulticastDelegate::FunNoParam_One()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicMulticastDelegate::FunNoParam_One"))
}
void ADeclareDynamicMulticastDelegate::FunNoParam_Two()
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicMulticastDelegate::FunNoParam_Two"))
}
void ADeclareDynamicMulticastDelegate::FunOneParam_One(int32 iValue)
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicMulticastDelegate::FunOneParam_One"))
}
void ADeclareDynamicMulticastDelegate::FunOneParam_Two(int32 iValue)
{
	UE_LOG(LogTemp,Log,TEXT("DeclareDynamicMulticastDelegate::FunOneParam_Two"))
} 
六、委托的调用
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "DelegateController.generated.h"
UCLASS()
class DELEGATE_API ADelegateController : public APlayerController
{
	GENERATED_BODY()
public:
	virtual void SetupInputComponent() override;
	//
	//	Call Declare Delegate
	//
	UFUNCTION()
	void CallDeclareDelegate();
	//
	//	Call Declare Multicast Delegate
	//
	UFUNCTION()
	void CallDeclareMulticastDelegate();
	//
	//	Call Declare Dynamic Delegate
	//
	UFUNCTION()
	void CallDeclareDynamicDelegate();
	//
	//	Call Declare Dynamic Multicast Delegate
	//
	UFUNCTION()
	void CallDeclareDynamicMulticastDelegate();
}; 
#include "DelegateController.h"
#include "DelegateGameMode.h"
#include "Kismet/GameplayStatics.h"
void ADelegateController::SetupInputComponent()
{
	Super::SetupInputComponent();
	InputComponent->BindAction("DeclareDelegate", IE_Pressed, this, &ThisClass::CallDeclareDelegate);
	InputComponent->BindAction("DeclareMulticastDelegate", IE_Pressed, this, &ThisClass::CallDeclareMulticastDelegate);
	InputComponent->BindAction("DeclareDynamicDelegate", IE_Pressed, this, &ThisClass::CallDeclareDynamicDelegate);
	InputComponent->BindAction("DeclareDynamicMulticastDelegate", IE_Pressed, this, &ThisClass::CallDeclareDynamicMulticastDelegate);
}
void ADelegateController::CallDeclareDelegate()
{
	if(GetWorld() == nullptr) return;
	
	const ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
	if(DelegateGameMode == nullptr) return;
	
	if(DelegateGameMode->DeclareDelegate_00.IsBound())
	{
		DelegateGameMode->DeclareDelegate_00.Execute();
	}
	DelegateGameMode->DeclareDelegate_01.ExecuteIfBound(true);
	DelegateGameMode->DeclareDelegate_02.ExecuteIfBound(true, 11);
	if(DelegateGameMode->DeclareDelegate_03.IsBound())
	{
		bool bValue = DelegateGameMode->DeclareDelegate_03.Execute();
	}
	if(DelegateGameMode->DeclareDelegate_04.IsBound())
	{
		bool bValue = DelegateGameMode->DeclareDelegate_04.Execute(true);
	}
}
void ADelegateController::CallDeclareMulticastDelegate()
{
	if(GetWorld() == nullptr) return;
	
	const ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
	if(DelegateGameMode == nullptr) return;
	
	if(DelegateGameMode->DeclareMulticastDelegate_00.IsBound())
	{
		DelegateGameMode->DeclareMulticastDelegate_00.Broadcast();
	}
	if(DelegateGameMode->DeclareMulticastDelegate_01.IsBound())
	{
		DelegateGameMode->DeclareMulticastDelegate_01.Broadcast(11);
	}
}
void ADelegateController::CallDeclareDynamicDelegate()
{
	if(GetWorld() == nullptr) return;
	
	const ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
	if(DelegateGameMode == nullptr) return;
	
	if(DelegateGameMode->DeclareDynamicDelegate_00.IsBound())
	{
		DelegateGameMode->DeclareDynamicDelegate_00.Execute();
	}
	DelegateGameMode->DeclareDynamicDelegate_01.ExecuteIfBound(11);
	if(DelegateGameMode->DeclareDynamicDelegate_02.IsBound())
	{
		bool bValue = DelegateGameMode->DeclareDynamicDelegate_02.Execute();
	}
	if(DelegateGameMode->DeclareDynamicDelegate_03.IsBound())
	{
		bool bValue = DelegateGameMode->DeclareDynamicDelegate_03.Execute(11);
	}
}
void ADelegateController::CallDeclareDynamicMulticastDelegate()
{
	if(GetWorld() == nullptr) return;
	
	const ADelegateGameMode* DelegateGameMode = Cast<ADelegateGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
	if(DelegateGameMode == nullptr) return;
	
	if(DelegateGameMode->DeclareDynamicMulticastDelegate_00.IsBound())
	{
		DelegateGameMode->DeclareDynamicMulticastDelegate_00.Broadcast();
	}
	if(DelegateGameMode->DeclareDynamicMulticastDelegate_01.IsBound())
	{
		DelegateGameMode->DeclareDynamicMulticastDelegate_01.Broadcast(11);
	}
} 
七、运行结果
1、运行开始

2、调用单播
![]()

3、调用多播
![]()

再次调用
![]()
4、调用动态单播
![]()

5、调用动态多播
![]()

6、运行结束




















