OnBoxOverlap not binding with OnComponentBeginOverlap.AddDynamic

Hello all,

I am running into an issue where my OnBoxOverlap(function I created) is not binding to my OnComponentBeginOverlap. The signature looks correct to me and I have UFUNCTION(). Any help or suggestions would be appreciated. I get the below error message. when attempting to play inside Unreal engine.

Output Message from visual studio:

Ensure condition failed: this->IsBound() [File:C:\Program Files\Epic Games\UE_5.1\Engine\Source\Runtime\Core\Public\Delegates\DelegateSignatureImpl.inl] [Line: 1037] 
Unable to bind delegate to 'OnBoxOverlap' (function might not be marked as a UFUNCTION or object may be pending kill)
A breakpoint instruction (__debugbreak() statement or a similar call) was executed in UnrealEditor.exe.

DelegateSignatureImpl.inl Lines 1024-1037 (Breakpoint at ensureMsgf)

	void __Internal_BindDynamic( UserClass* InUserObject, typename TMethodPtrResolver< UserClass >::FMethodPtr InMethodPtr, FName InFunctionName )
	{
		check( InUserObject != nullptr && InMethodPtr != nullptr );

		// NOTE: We're not actually storing the incoming method pointer or calling it.  We simply require it for type-safety reasons.

		// NOTE: If you hit a compile error on the following line, it means you're trying to use a non-UObject type
		//       with this delegate, which is not supported
		this->Object = Cast<UObject>(InUserObject);

		// Store the function name.  The incoming function name was generated by a macro and includes the method's class name.
		this->FunctionName = InFunctionName;

		ensureMsgf(this->IsBound(), TEXT("Unable to bind delegate to '%s' (function might not be marked as a UFUNCTION or object may be pending kill)"), *InFunctionName.ToString());
	}

Weapon.h

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

#pragma once

#include "CoreMinimal.h"
#include "Items/Item.h"
#include "Weapon.generated.h"

class USoundBase;
class UBoxComponent;

/**
 * 
 */
UCLASS()
class SLASH_API AWeapon : public AItem
{
	GENERATED_BODY()
public:
	AWeapon();
	void Equip(USceneComponent* Inparent, FName InSocketName);
	void AttachMeshToSocket(USceneComponent* Inparent, const FName& InSocketName);
	void Unequip(USceneComponent* Inparent, FName InSocketName);
protected:
	virtual void BeginPlay() override;

	virtual void OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) override;
	virtual void OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) override;\

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

private:

	UPROPERTY(EditAnywhere)
		USoundBase* EquipSound;

	UPROPERTY(VisibleAnywhere)
		UBoxComponent* WeaponBox;

	UPROPERTY(VisibleAnywhere)
		USceneComponent* BoxTraceStart;

	UPROPERTY(VisibleAnywhere)
		USceneComponent* BoxTraceEnd;

public:

	FORCEINLINE UBoxComponent* GetWeaponBox() const { return WeaponBox; };
};

Weapon.cpp

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


#include "Items/weapons/Weapon.h"
#include "Characters/SlashCharacter.h"
#include "Kismet/GameplayStatics.h"
#include "Components/SphereComponent.h"
#include "Components/BoxComponent.h"
#include "Kismet/KismetSystemLibrary.h"
#include "interfaces/HitInterface.h"
#include "Components/PrimitiveComponent.h"
#include "DebugMacros.h"
#include "..\..\..\..\..\Intermediate\ProjectFiles\DebugMacros.h"

AWeapon::AWeapon()
{
	WeaponBox = CreateDefaultSubobject<UBoxComponent>(TEXT("Weapon Box"));
	WeaponBox->SetupAttachment(GetRootComponent());
	WeaponBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
	WeaponBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap);
	WeaponBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);

	BoxTraceStart = CreateDefaultSubobject<USceneComponent>(TEXT("Box Trace Start"));
	BoxTraceStart->SetupAttachment(GetRootComponent());

	BoxTraceEnd = CreateDefaultSubobject<USceneComponent>(TEXT("Box Trace End"));
	BoxTraceEnd->SetupAttachment(GetRootComponent());
}

void AWeapon::BeginPlay()
{
	Super::BeginPlay();
	
	WeaponBox->OnComponentBeginOverlap.AddDynamic(this, &AWeapon::OnBoxOverlap);
}

void AWeapon::Equip(USceneComponent* Inparent, FName InSocketName)
{
	AttachMeshToSocket(Inparent, InSocketName);
	
	if (EquipSound)
	{
		UGameplayStatics::PlaySoundAtLocation(
			this,
			EquipSound,
			GetActorLocation()
		);
	}

	if (Sphere) 
	{
		Sphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	}
}

void AWeapon::AttachMeshToSocket(USceneComponent* Inparent, const FName& InSocketName)
{
	FAttachmentTransformRules TransformRules(EAttachmentRule::SnapToTarget, true);
	ItemMesh->AttachToComponent(Inparent, TransformRules, InSocketName);
}

void AWeapon::Unequip(USceneComponent* Inparent, FName InSocketName)
{
}

void AWeapon::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	Super::OnSphereOverlap(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult);
}

void AWeapon::OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	Super::OnSphereEndOverlap(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex);
}

void AWeapon::OnBoxOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (GEngine)
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("Some debug message!"));

	const FVector Start = BoxTraceStart->GetComponentLocation();
	const FVector End = BoxTraceEnd->GetComponentLocation();

	PRINT_TO_SCREEN("here")
	DRAW_LINE(Start, End)

	TArray<AActor*> ActorsToIgnore;
	ActorsToIgnore.Add(this);
	
	FHitResult BoxHit;

	UKismetSystemLibrary::BoxTraceSingle(   
		this,
		Start,
		End,
		FVector(5.f, 5.f, 5.f),
		BoxTraceStart->GetComponentRotation(),
		ETraceTypeQuery::TraceTypeQuery1,
		false,
		ActorsToIgnore,
		EDrawDebugTrace::ForDuration,
		BoxHit,
		true
		);

	if (BoxHit.GetActor())
	{
		IHitInterface* HitInterface = Cast<IHitInterface>(BoxHit.GetActor());
		if (HitInterface)
		{
			HitInterface->GetHit(BoxHit.ImpactPoint);
		}
	}
}

This is very weird, but the OnBoxOverlap is somehow recognizable function and will be triggered only when you don’t add a line

BoxComponent->OnComponentBeginOverlap.AddDynamic(this, &AWeapon::OnBoxOverlap);

If you add this line, it won’t trigger Overlap event. So rather rename your method to something else and it should be fine.

a) You need to move your bind to the contructor (CDO)
b) You need to add SetGenerateOverlapEvents to your box component

Here’s an example of some code I used a while ago

// Sets default values
ATest1Character::ATest1Character()
{
	PrimaryActorTick.bCanEverTick = true;
	bc = CreateDefaultSubobject<UBoxComponent>(TEXT("b"));
	bc->SetupAttachment(GetRootComponent());
	bc->SetGenerateOverlapEvents(true);
	bc->SetBoxExtent(FVector(400, 400, 400));
	
	bc->SetCollisionProfileName(FName("OverlapAll"));
	bc->OnComponentBeginOverlap.AddDynamic(this, &ATest1Character::OnOverlapBegin);
	
}


void ATest1Character::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) {	
	overlapDel.Broadcast(OtherActor->GetName());
}

OFC change what you need to get yours running correctly.

Thanks for the response everyone. I figured it out eventually. The issues was me having a random “/” in my Weapon.h file. its was on the end of my

virtual void OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) override;\

But it was off the screen to the right so I did not notice it over there.

1 Like

I’m adding this here because, after years of programming, I still have made this stupid error:

Be sure that the OnBoxOverlap function that you are calling has the UFUNCTION specifier :sweat_smile: