A delegate is a special type of struct to which function(s) can be binded and invoked later
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
// Delegate signature
DECLARE_DELEGATE_TwoParams(FMyDelegateA, int32 /* FirstVar */, float /* SecondVar */);
struct RawStruct {
void StructFunction(int32 Var1, float Var2) {}
};
class RawClass {
public:
void MyClassFunction(int32 Var1, float Var2) {}
};
UCLASS()
class TESTING_API AMyActor : public AActor {
GENERATED_BODY()
public:
FMyDelegateA DelegateVarA; // Delegate declaration, No UPROPERTY() required
UFUNCTION()
void MyUFunction(int32 Var1, float Var2) {} // Function decleration
void MyFunction(int32 Var1, float Var2) {} // Function decleration, No UFUNCTION required
static void MyStaticFunction(int32 Var1, float Var2) {} // Static Function decleration, No UFUNCTION required
void BeginPlay() {
Super::BeginPlay();
// Binding
DelegateVarA.BindUObject(this, &AMyActor::MyFunction); // Binds delegate to the given UObject (first argument) and it's function
DelegateVarA.BindUFunction(this, TEXT("MyUFunction")); // Binds delegate to the given function of UObject by name
DelegateVarA.BindRaw(&MyStruct, &RawStruct::StructFunction); // Used to bind to non reflection exposed structs
DelegateVarA.BindRaw(MyClass, &RawClass::MyClassFunction); // Used to bind to non reflection exposed classes
DelegateVarA.BindStatic(&AMyActor::MyStaticFunction);
DelegateVarA.BindLambda([](int32 Var1, float Var2) {});
DelegateVarA.BindWeakLambda(this, [](int32 Var1, float Var2) {}); // Unbinds itself when given UObject (first argument) goes out of scope i.e. it's lifetime ends
DelegateVarA.BindSP(MySharedClass.ToSharedRef(), &RawClass::MyClassFunction);
DelegateVarA.BindThreadSafeSP(MySafeSharedClass.ToSharedRef(), &RawClass::MyClassFunction);
// Checking
bool bIsBound = DelegateVarA.IsBound();
// Invoking
DelegateVarA.Execute(23, 8.7);
bool IsBoundA = DelegateVarA.ExecuteIfBound(23, 8.7);
// Unbinding
DelegateVarA.Unbind();
}
private:
RawStruct MyStruct;
RawClass* MyClass = new RawClass();
TSharedPtr<RawClass> MySharedClass = TSharedPtr<RawClass>(new RawClass());
TSharedPtr<RawClass, ESPMode::ThreadSafe> MySafeSharedClass = TSharedPtr<RawClass, ESPMode::ThreadSafe>(new RawClass());
};
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
// Delegate signature declaration
DECLARE_DELEGATE_RetVal_TwoParams(int32, FMyDelegateB, int32 /* FirstVar */, float /* SecondVar */);
struct RawStruct {
int StructFunction(int32 Var1, float Var2) { return 1; }
};
class RawClass {
public:
int ClassFunction(int32 Var1, float Var2) { return 2; }
};
UCLASS()
class TESTING_API AMyActor : public AActor {
GENERATED_BODY()
public:
FMyDelegateB DelegateVarB; // Delegate declaration, No UPROPERTY() required
UFUNCTION()
int MyUFunction(int32 Var1, float Var2) { return 3; } // Function decleration
int MyFunction(int32 Var1, float Var2) { return 4; } // Function decleration, No UFUNCTION required
static int MyStaticFunction(int32 Var1, float Var2) { return 5; } // Static Function decleration, No UFUNCTION required
void BeginPlay() {
Super::BeginPlay();
// Binding
DelegateVarB.BindUObject(this, &AMyActor::MyFunction); // Binds delegate to the given UObject (first argument) and it's function
DelegateVarB.BindUFunction(this, TEXT("MyUFunction")); // Binds delegate to the given function of UObject by name
DelegateVarB.BindRaw(&MyStruct, &RawStruct::StructFunction); // Used to bind to non reflection exposed structs
DelegateVarB.BindRaw(MyClass, &RawClass::ClassFunction); // Used to bind to non reflection exposed classes
DelegateVarB.BindStatic(&AMyActor::MyStaticFunction);
DelegateVarB.BindLambda([](int32 Var1, float Var2) { return 6; });
DelegateVarB.BindWeakLambda(this, [](int32 Var1, float Var2) { return 7; }); // Unbinds itself when given UObject (first argument) goes out of scope i.e. it's lifetime ends
DelegateVarB.BindSP(MySharedClass.ToSharedRef(), &RawClass::ClassFunction);
DelegateVarB.BindThreadSafeSP(MySafeSharedClass.ToSharedRef(), &RawClass::ClassFunction);
// Checking
bool bIsBound = DelegateVarB.IsBound();
// Invoking
int32 ReturnValue = DelegateVarB.Execute(23, 8.7); // ExecuteIfBound() does not work
// Unbinding
DelegateVarB.Unbind();
}
private:
RawStruct MyStruct;
RawClass* MyClass = new RawClass();
TSharedPtr<RawClass> MySharedClass = TSharedPtr<RawClass>(new RawClass());
TSharedPtr<RawClass, ESPMode::ThreadSafe> MySafeSharedClass = TSharedPtr<RawClass, ESPMode::ThreadSafe>(new RawClass());
};
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
// Delegate signature declaration
DECLARE_MULTICAST_DELEGATE_TwoParams(FMyDelegateC, int32 /* FirstVar */, float /* SecondVar */);
struct RawStruct {
void StructFunction(int32 Var1, float Var2) {}
};
class RawClass {
public:
void ClassFunction(int32 Var1, float Var2) {}
};
UCLASS()
class TESTING_API AMyActor : public AActor {
GENERATED_BODY()
public:
FMyDelegateC DelegateVarC; // Delegate declaration, No UPROPERTY() required
UFUNCTION()
void MyUFunction(int32 Var1, float Var2) {} // Function decleration
void MyFunction(int32 Var1, float Var2) {} // Function decleration, No UFUNCTION required
static void MyStaticFunction(int32 Var1, float Var2) {} // Static Function decleration, No UFUNCTION required
void BeginPlay() {
Super::BeginPlay();
// Binding
DelegateHandle = DelegateVarC.AddUObject(this, &AMyActor::MyFunction); // Adds delegate to the given UObject (first argument) and it's function
DelegateHandle = DelegateVarC.AddUFunction(this, TEXT("MyUFunction")); // Adds delegate to the given function of UObject by name
DelegateHandle = DelegateVarC.AddRaw(&MyStruct, &RawStruct::StructFunction); // Used to bind to non reflection exposed structs
DelegateHandle = DelegateVarC.AddRaw(MyClass, &RawClass::ClassFunction); // Used to bind to non reflection exposed classes
DelegateHandle = DelegateVarC.AddStatic(&AMyActor::MyStaticFunction);
DelegateHandle = DelegateVarC.AddLambda([](int32 Var1, float Var2) {});
DelegateHandle = DelegateVarC.AddWeakLambda(this, [](int32 Var1, float Var2) {}); // Unbinds itself when given UObject (first argument) goes out of scope i.e. it's lifetime ends
DelegateHandle = DelegateVarC.AddSP(MySharedClass.ToSharedRef(), &RawClass::ClassFunction);
DelegateHandle = DelegateVarC.AddThreadSafeSP(MySafeSharedClassA.ToSharedRef(), &RawClass::ClassFunction);
// Checking
bool bIsBound = DelegateVarC.IsBound();
bool bIsBoundToObject = DelegateVarC.IsBoundToObject(this);
// Invoking
DelegateVarC.Broadcast(23, 8.7);
// Unbinding
DelegateVarC.Remove(DelegateHandle);
DelegateVarC.RemoveAll(this); // Removes all functions bound by given object
DelegateVarC.Clear();
}
protected:
FDelegateHandle DelegateHandle;
private:
RawStruct MyStruct;
RawClass* MyClass = new RawClass();
TSharedPtr<RawClass> MySharedClass = TSharedPtr<RawClass>(new RawClass());
TSharedPtr<RawClass, ESPMode::ThreadSafe> MySafeSharedClassA = TSharedPtr<RawClass, ESPMode::ThreadSafe>(new RawClass());
};
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
// Delegate signature
UDELEGATE()
DECLARE_DYNAMIC_DELEGATE_TwoParams(FMyDelegateD, int32, FirstVar, float, SecondVar);
UCLASS()
class TESTING_API AMyActor : public AActor {
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite)
FMyDelegateD DelegateVarD; // Delegate declaration
UFUNCTION()
void MyUFunction(int32 Var1, float Var2) { UE_LOG(LogTemp, Warning, TEXT("MyUFunction")); }
void BeginPlay() {
Super::BeginPlay();
// Binding
DelegateVarD.BindDynamic(this, &AMyActor::MyUFunction); // Make sure binding function is a UFUNCTION()
// Checking
bool bIsBound = DelegateVarD.IsBound();
// Invoking
DelegateVarD.Execute(23, 8.7);
bool IsBoundA = DelegateVarD.ExecuteIfBound(23, 8.7);
// Unbinding
DelegateVarD.Unbind();
}
};
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
// Delegate signature
UDELEGATE()
DECLARE_DYNAMIC_DELEGATE_RetVal_TwoParams(int32, FMyDelegateE, int32, FirstVar, float, SecondVar);
UCLASS()
class TESTING_API AMyActor : public AActor {
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite)
FMyDelegateE DelegateVarE; // Delegate declaration
UFUNCTION()
int32 MyUFunction(int32 Var1, float Var2) { return 1; }
void BeginPlay() {
Super::BeginPlay();
// Binding
DelegateVarE.BindDynamic(this, &AMyActor::MyUFunction); // Make sure binding function is a UFUNCTION()
// Checking
bool bIsBound = DelegateVarE.IsBound();
// Invoking
int32 ReturnValue = DelegateVarE.Execute(23, 8.7);
// Unbinding
DelegateVarE.Unbind();
}
};
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
// Delegate signature
UDELEGATE()
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FMyDelegateF, int32, FirstVar, float, SecondVar);
UCLASS()
class TESTING_API AMyActor : public AActor {
GENERATED_BODY()
public:
UPROPERTY(BlueprintAssignable, BlueprintCallable)
FMyDelegateF DelegateVarF; // Delegate declaration
UFUNCTION()
void MyUFunction(int32 Var1, float Var2) {}
void BeginPlay() {
Super::BeginPlay();
// Binding
DelegateVarF.AddDynamic(this, &AMyActor::MyUFunction); // Make sure binding function is a UFUNCTION()
DelegateVarF.AddUniqueDynamic(this, &AMyActor::MyUFunction); // Makes sure same function isn't added twice
// Checking
bool bIsBound = DelegateVarF.IsBound(); // Checks if any function is bound
bool bIsAlreadyBound = DelegateVarF.IsAlreadyBound(this, &AMyActor::MyUFunction); // Checks if specific function is bound
// Invoking
DelegateVarF.Broadcast(23, 8.7);
// Unbinding
DelegateVarF.RemoveDynamic(this, &AMyActor::MyUFunction);
DelegateVarF.RemoveAll(this); // Unbinds all function of given object
DelegateVarF.Clear(); // Unbinds all
}
};
References: