省流:
// 定义类型
DECLARE_DELEGATE(FDelegateTaskA)
DECLARE_DELEGATE_OneParam(FDelegateTaskB, bool)
DECLARE_DELEGATE_RetVal(bool, FDelegateTaskC)
DECLARE_DELEGATE_RetVal_OneParam(int32, FDelegateTaskD, FString&)
// 声明实例
FDelegateTaskA DelegateTaskA;
FDelegateTaskB DelegateTaskB;
FDelegateTaskC DelegateTaskC;
FDelegateTaskD DelegateTaskD;
// 绑定
XXX.BindRaw // 普通C函数
XXX.BindSP // 共享指针
XXX.BindUObject // UObject的函数
XXX.BindStatic // 全局静态
XXX.BindUFunction // UFunction
// 调用
if (XXX.IsBound())
{
XXX.Execute()
}
XXX.ExecuteIfBound()
// 记得解绑定
// XXX.UnBind()
// 多播
// 定义
DECLARE_MULTICAST_DELEGATE(FDelegateTaskE)
// 绑定函数变成 Add开头,可以加多个,调用变成 Broadcast 记得最后 Clear
一,原生C代理
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
DECLARE_DELEGATE(FDelegateTaskA)
DECLARE_DELEGATE_OneParam(FDelegateTaskB, bool)
DECLARE_DELEGATE_RetVal(bool, FDelegateTaskC)
DECLARE_DELEGATE_RetVal_OneParam(int32, FDelegateTaskD, FString&)
static void PrintF(FString InString)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Red, InString);
}
}
class FClassA
{
public:
FDelegateTaskA DelegateTaskA;
FDelegateTaskB DelegateTaskB;
FDelegateTaskC DelegateTaskC;
FDelegateTaskD DelegateTaskD;
void Init()
{
bool bIsRight = false;
int32 Index = INDEX_NONE;
FString InString = TEXT("Hello");
bIsRight = DelegateTaskA.ExecuteIfBound();
bIsRight = DelegateTaskB.ExecuteIfBound(bIsRight);
if (DelegateTaskC.IsBound())
{
bIsRight = DelegateTaskC.Execute();
}
if (DelegateTaskD.IsBound())
{
Index = DelegateTaskD.Execute(InString);
}
}
};
class FClassB
{
public:
explicit FClassB(FClassA* InObjA)
: ObjA(InObjA)
{
if (ObjA)
{
ObjA->DelegateTaskA.BindRaw(this, &FClassB::ExcuteA);
ObjA->DelegateTaskB.BindRaw(this, &FClassB::ExcuteB);
ObjA->DelegateTaskC.BindRaw(this, &FClassB::ExcuteC);
ObjA->DelegateTaskD.BindRaw(this, &FClassB::ExcuteD);
}
}
~FClassB()
{
if (ObjA)
{
ObjA->DelegateTaskA.Unbind();
ObjA->DelegateTaskB.Unbind();
ObjA->DelegateTaskC.Unbind();
ObjA->DelegateTaskD.Unbind();
ObjA->Init();
delete ObjA;
ObjA = nullptr;
}
}
void ExcuteA()
{
PrintF(TEXT("ExcuteA"));
}
void ExcuteB(bool bIsRight)
{
PrintF(TEXT("ExcuteB"));
}
bool ExcuteC()
{
PrintF(TEXT("ExcuteC"));
return false;
}
int32 ExcuteD(FString& InString)
{
PrintF(TEXT("ExcuteD"));
return 0;
}
private:
FClassA* ObjA;
};
调用随便找个beginplay
void AMyActor::BeginPlay()
{
Super::BeginPlay();
FClassA* ObjA = new FClassA();
FClassB* ObjB = new FClassB(ObjA);
ObjA->Init();
delete ObjB;
ObjA = nullptr;
ObjB = nullptr;
}
二,共享指针代理
class FClassB : public TSharedFromThis<FClassB>
{
public:
FClassB() = default;
void Init()
{
ObjA = MakeShareable(new FClassA());
ObjA->DelegateTaskA.BindSP(this, &FClassB::ExcuteA);
ObjA->DelegateTaskB.BindSP(this, &FClassB::ExcuteB);
ObjA->DelegateTaskC.BindSP(this, &FClassB::ExcuteC);
ObjA->DelegateTaskD.BindSP(this, &FClassB::ExcuteD);
ObjA->Init();
}
~FClassB()
{
if (ObjA.Get())
{
ObjA->DelegateTaskA.Unbind();
ObjA->DelegateTaskB.Unbind();
ObjA->DelegateTaskC.Unbind();
ObjA->DelegateTaskD.Unbind();
ObjA->Init();
}
}
// ...
FORCEINLINE TSharedRef<FClassA> GetA() { return ObjA.ToSharedRef(); }
private:
TSharedPtr<FClassA> ObjA;
};
调用
TSharedPtr<FClassB> ObjB = MakeShareable(new FClassB());
ObjB->Init();
三,UObject代理
在Actor里面定义代理
FDelegateTaskA DelegateTaskA;
void ActorPrint()
{
PrintF("Hello");
}
然后绑定调用
void AMyActor::BeginPlay()
{
Super::BeginPlay();
DelegateTaskA.BindUObject(this, &AMyActor::ActorPrint);
bool bSucc = DelegateTaskA.ExecuteIfBound();
}
四,全局静态代理
static void StaticPrint()
{
PrintF("StaticPrint");
}
void AMyActor::BeginPlay()
{
Super::BeginPlay();
DelegateTaskA.BindStatic(StaticPrint);
bool bSucc = DelegateTaskA.ExecuteIfBound();
}
五,UFunction代理
UFUNCTION()
void ActorPrint()
{
PrintF("Hello");
}
void AMyActor::BeginPlay()
{
Super::BeginPlay();
DelegateTaskA.BindUFunction(this, TEXT("ActorPrint"));
bool bSucc = DelegateTaskA.ExecuteIfBound();
}
六,多播
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
DECLARE_MULTICAST_DELEGATE(FDelegateTaskE)
static void PrintF(FString InString)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Red, InString);
}
}
class FClassA
{
public:
FDelegateTaskE DelegateTaskE;
};
class FClassB
{
public:
FClassB() = default;
void Init()
{
ObjA = new FClassA();
ObjA->DelegateTaskE.AddRaw(this, &FClassB::ExcuteA);
ObjA->DelegateTaskE.AddRaw(this, &FClassB::ExcuteB);
ObjA->DelegateTaskE.Broadcast();
ObjA->DelegateTaskE.Clear();
delete ObjA;
}
void ExcuteA()
{
PrintF(TEXT("ExcuteA"));
}
void ExcuteB()
{
PrintF(TEXT("ExcuteB"));
}
private:
FClassA* ObjA;
};
FClassB* B = new FClassB();
B->Init();
多播就定义不一样,bindXXX变成addXXX
调用变成 Broadcast 清空用Clear 其他都一样
七,动态单播多播
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "C_Function.generated.h"
DECLARE_DYNAMIC_DELEGATE_OneParam(FDelegateTaskA, const FString&, Str_C);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDelegateTaskB, const FString&, Str_C);
static void PrintF(FString InString)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Red, InString);
}
}
UCLASS()
class UMyClass : public UObject
{
GENERATED_BODY()
public:
FDelegateTaskA DelegateTaskA;
FDelegateTaskB DelegateTaskB;
void Init()
{
DelegateTaskA.BindDynamic(this, &UMyClass::MyPrintA);
DelegateTaskA.BindDynamic(this, &UMyClass::MyPrintB);
const FString Hello = TEXT("Hello");
bool bSucc = DelegateTaskA.ExecuteIfBound(Hello); // 只打印了 B 因为是单播
DelegateTaskA.Unbind();
// DelegateTaskB.AddDynamic()
// DelegateTaskB.RemoveAll()
}
UFUNCTION()
void MyPrintA(const FString& InStr)
{
PrintF(InStr + TEXT("A"));
}
UFUNCTION()
void MyPrintB(const FString& InStr)
{
PrintF(InStr + TEXT("B"));
}
};
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "C_Function.generated.h"
DECLARE_DYNAMIC_DELEGATE_OneParam(FDelegateTaskA, const FString&, Str_C);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDelegateTaskB, const FString&, Str_C);
static void PrintF(FString InString)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Red, InString);
}
}
UCLASS()
class UMyClass : public UObject
{
GENERATED_BODY()
public:
FDelegateTaskA DelegateTaskA;
FDelegateTaskB DelegateTaskB;
void Init()
{
DelegateTaskB.AddDynamic(this, &UMyClass::MyPrintA);
DelegateTaskB.AddDynamic(this, &UMyClass::MyPrintB);
const FString Hello = TEXT("Hello");
DelegateTaskB.Broadcast(Hello); // 只打印了 B 因为是单播
DelegateTaskB.RemoveAll(this);
DelegateTaskB.Broadcast(Hello);
// DelegateTaskB.AddDynamic()
// DelegateTaskB.RemoveAll()
}
UFUNCTION()
void MyPrintA(const FString& InStr)
{
PrintF(InStr + TEXT("A"));
}
UFUNCTION()
void MyPrintB(const FString& InStr)
{
PrintF(InStr + TEXT("B"));
}
};
八,多态事件代理
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
static void PrintF(FString InString)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Red, InString);
}
}
class FEventTask
{
public:
virtual ~FEventTask() = default;
DECLARE_EVENT_OneParam(FEventTask, FEventTaskDeclare, const FString&)
virtual FEventTaskDeclare& OnEventTaskDeclare() = 0;
DECLARE_EVENT_OneParam(FEventTask, FEventDeclare, const FString&)
FEventDeclare& OnEventDeclare() { return EventDeclare; }
private:
FEventDeclare EventDeclare;
};
class FEventTaskChild : public FEventTask
{
public:
DECLARE_DERIVED_EVENT(FEventTaskChild, FEventTask::FEventTaskDeclare, FEventTaskName);
virtual FEventTaskName& OnEventTaskDeclare() override { return EventTaskName; }
void Init()
{
FString NewStr = "Hello";
OnEventTaskDeclare().Broadcast(NewStr);
NewStr = "World";
OnEventDeclare().Broadcast(NewStr);
}
private:
FEventTaskName EventTaskName;
};
class FATask
{
public:
void Init()
{
FEventTaskChild* Child = new FEventTaskChild();
Child->OnEventTaskDeclare().AddRaw(this, &FATask::ExcuteA);
Child->OnEventTaskDeclare().AddRaw(this, &FATask::ExcuteB);
Child->OnEventDeclare().AddRaw(this, &FATask::ExcuteA);
Child->OnEventDeclare().AddRaw(this, &FATask::ExcuteB);
Child->Init();
}
void ExcuteA(const FString& InStr)
{
PrintF(TEXT("ExcuteA") + InStr);
}
void ExcuteB(const FString& InStr)
{
PrintF(TEXT("ExcuteB") + InStr);
}
void ExcuteC(const FString& InStr)
{
PrintF(TEXT("ExcuteC") + InStr);
}
void ExcuteD(const FString& InStr)
{
PrintF(TEXT("ExcuteD") + InStr);
}
};