Add a delegate to OnComponentBeginOverlap in C++

Hi guys, I am trying to attach a delegate to the OnComponentBeginOverlap event.

Here is the header:

UCLASS()
class ASlidingDoorTrigger : public AActor
{
	GENERATED_UCLASS_BODY()

public:
	UPROPERTY(VisibleAnywhere, Category = "Triggers")
	TSubobjectPtr<UBoxComponent> TriggerBox;

	UPROPERTY(EditAnywhere, Category = "Static Meshes")
	AStaticMeshActor* SlidingDoor;

private:
	void OnBeginOverlap();
	void OnEndOverlap();
};

And the source file:

ASlidingDoorTrigger::ASlidingDoorTrigger(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
	this->TriggerBox = PCIP.CreateDefaultSubobject<UBoxComponent>(this, TEXT("BoxTrigger_SlidingDoor"));
	this->TriggerBox->OnComponentBeginOverlap.Add(&ASlidingDoorTrigger::OnBeginOverlap);
	this->TriggerBox->OnComponentEndOverlap.Add(&ASlidingDoorTrigger::OnBeginOverlap);
	this->RootComponent = this->TriggerBox;
}

void ASlidingDoorTrigger::OnBeginOverlap()
{
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(0, 10.0f, FColor::White, TEXT("Begin Overlap"));
	}
}

void ASlidingDoorTrigger::OnEndOverlap()
{
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(0, 10.0f, FColor::White, TEXT("End Overlap"));
	}
}

The problem is that I need to pass a TSciptDelagate to the Add function, but I don’t know it’s signature. Also I want to pass a delegate with the “void Function()” signature. Can you help me out?

1 Like

First of, you have to declare your OnBeginOverlap and OnEndOverlap functions as follow:

UFUNCTION()
void OnBeginOverllap(AActor* Other);
UFUNCTION()
void OnEndOverlap(AActor* Other);

Delegates must be UFUNCTIONs, and must match delegate signature as well, so you can’t pass void Function() into this delegate.

Also, since it’s dynamic multicast you have to add it like this:

OnComponentBeginOverlap.AddDynamic(this, &ASlidingDoorTrigger::OnBeginOverlap);

First parameter is the pointer to the object that will execute the function passed as second parameter.

P.S. You don’t need to use this in the constructor in this case, it’s just excess.

Thanks mate. I am at work now. Will try it out when I get back home :slight_smile:

BTW mate, where I can see the signatures of all delegates? I am currently watching the documentation for the TScriptDelegate and there nothing that tells me what the signature is?

That is actually base-class for delegates.

You can find signatures list and where they are declared in the docs, for example - Components | Unreal Engine Documentation, lists all the delegates used in components. Check marshaling category to find out delegate parameters.

There should be something like Go to definition in Visual Studio, just highlight type, right click and look for something like find declaration/go to definition. I use Visual Assist X add-on for Visual Studio, there is such feature, but i’m not sure about the stock VS; though it should have it too.

P.S. Inside your (Begin/End)Overlap function you check for GEngine, i believe that if delegate happened to trigger, there is no way GEngine could be null, something really weird must happen, but if that happened, engine will crash much earlier before your delegate :slight_smile:

Thanks for the info mate, you really helped. I use Visual Assist X too, it’s a very nice add-on, especially for C++

It worked mate. The signature of the function is actually this:

UFUNCTION()
void OnOverlap(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

Thank you very much.

Oh, indeed. I’ve been referring to OnActorBeginOverlap delegate apparently :slight_smile:

You’re welcome, feel free to ask more :slight_smile:

For those reading this with later engine versions (4.7+) here is the now correct method:

Function definitions should look like this:

	UFUNCTION()
		void OnXXXOverlapBegin(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);

	UFUNCTION()
		void OnXXXOverlapEnd(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

Then in the constructor or wherever you desire you set it up with this:

	XXXComponent = ObjectInitializer.CreateDefaultSubobject<USphereComponent>(this, TEXT("XXX"));
	XXXComponent->SetSphereRadius(2000.0f);
	XXXComponent->AttachParent = RootComponent;
	XXXComponent->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
	XXXComponent->SetCollisionResponseToChannel(ECC_XXX, ECollisionResponse::ECR_Overlap);

	XXXComponent->OnComponentBeginOverlap.AddDynamic(this, &AXXXCharacter::OnXXXOverlapBegin);
	XXXComponent->OnComponentEndOverlap.AddDynamic(this, &AXXXCharacter::OnXXXOverlapEnd);

Beautiful. Thanks.

By the way, is this kind of stuff documented, or are we just expected to figure it out ourselves?

I figured it out, not sure if it is documented or not, but it probably is. It is just these things change with every version. At least since I figured it out, no one else has to for this version.

For better documentation, even though it is 4.6, see this URL. It still has the same setup.

In 4.13 there seems to be an additional param in front of the param list:

void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp,....

This forum post is old, but I keep coming back to it, and the info is too outdated, so here’s a more up to date way to do OnCompnentBeginOverlap() that works with at least 4.22.3. The difference in parameters seems to be the UPrimitiveComponent* OverlappedComp parameter.

This goes in your .h file:

UFUNCTION()
	void OnMonkeyBeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

And this goes into your .cpp file:

AMonkey::AMonkey()
{
    ...
    // ^ Definition of MonkeyMesh up here

    //Then add the delegate:
	MonkeyMesh->OnComponentBeginOverlap.AddDynamic(this, &AMonkey::OnMonkeyBeginOverlap);
}

void AMonkey::OnMonkeyBeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	//Make the monkey explode here, or something...
}

I guess the parameters for OnComponentBeginOverlap() have changed, so this is the only way I could get it to work. Here is a link to the documentation that I found on this (if you’re into that stuff):

In 4.27.2 the parameters set for on_begin_overlap_delegate is next:
(class UPrimitiveComponent* OtherComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp2, int32 OtherBodyIndex, bool someBool, const FHitResult& hitResult)