OnBeginOverlap from c++ not working

I found several posts here about it, but I cannot find what I’m missing in this case, so maybe someone else here is able to see that

CombatMode.h

class LASTFANTASY_API ACombatMode : public AStaticMeshActor
{
	GENERATED_BODY()
	
	
public:
	ACombatMode();
	void Enable();
	void BlurEnvironment();

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

//UPROPERTY
public:
	UPROPERTY(BlueprintReadWrite, VisibleAnywhere, Category = "Trigger")
		UBoxComponent* TriggerBox;    	
};

CombatMode.cpp

CombatMode::ACombatMode()
{

	TriggerBox = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerBox"));
	TriggerBox->AttachToComponent(GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
	TriggerBox->bGenerateOverlapEvents = true;
	SetActorEnableCollision(true);
	TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &ACombatMode::OnOverlapBegin);	
}


void ACombatMode::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	Enable();
}

void ACombatMode::Enable()
{
	//GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("This is an on screen message!"));
	debug(TEXT("EnableCombat Mode")); // macro for addOnScreenDebugMessage
	BlurEnvironment();
}

void ACombatMode::BlurEnvironment()
{

}

I don’t see the debug output here.
What am I missing in this case?

1 Like

Do you need to actually set a RootComponent? (I also ask this to the community, not rhetorically!)

In my C++ actors, following from examples, I’ve always called CreateDefaultSubobject, like you have. Then with one of them, set it as the RootComponent. So in your case, something like:

...
TriggerBox = CreateDefaultSubobject<UBoxComponent>( TEXT( "TriggerBox" ) );
RootComponent = TriggerBox;
...

I’m wondering if there must be a RootComponent set, before you can then call AttachToComponent( GetRootComponent()…, lest that return a NULL/nullptr?

Thanks! I looked at some of my code, to try and help, and thought “Hmm, do I need to do this?” But yup, I still do, heh.

Normally you would, yes, but the OP is using AStaticMeshActor as his base class (for some reason) which I assume has a UStaticMeshComponent added by default and set as the root component.

hm but this doesn’t answer my question in any case :frowning:

Open the console (~ or ` key) while in play mode and type “show collision” to show the collision bounds. Check if there is a collision bounds as you don’t set the size of the box component. Also not sure if you need to turn off simulate physics or not as you might be generating collisions and not triggering.

Hi and Thanks for the reply. I adjusted the size of the Trigger Box on the component blueprints.
When using eventonActoroverlap for the same component in their bp, everything woks fine. So I assume I missed something in the Code

A couple things I would try for debugging this:

  1. Add debug output to
    Combat::ACombatMode() to verify it’s
    getting called properly
  2. ‘show
    collision’ while in gameplay to
    check if the box is where you expect
    it to be, and if it ever overlaps
    anything you would expect to trigger
    overlap events.
  3. Check if whatever
    you’re checking overlap with also
    has overlap enabled with overlap
    channels also enabled.
  4. Double
    check that UBoxComponent has the
    expected default overlap channels
    when spawned under ‘Collision’
    settings. (Spawn it in Blueprints
    and take a look at it there).

All this checks seems to be correct, because it works in the bp of the same component :frowning:

For those who are having the same issue, here is what I figured out

If you create a blueprint based, on a c++ class and later in that code (while the bp has already been created) you are adding “AddDynamic”-Bindings, you may have to delete and recreate the bp after compile, because the binding seems not to be recognized when the BP has created before

You’ve told the actor to collide and you’ve told the component to trigger overlaps and you’ve tied your respondent method to the overlap event; but what you’ve missed is telling the engine/component how to decide if the overlap has been triggered. Specifically, you need to tell the component what other objects should trigger collisions or overlaps and which should be ignored. This is done in UE4 by assigning the component a collision profile and/or by setting specific responses to available collision channels.

In your component setup you’ll want to add something like this:

//setting a collision profile; each profile has default behaviors defined per channel
TriggerBox ->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);

//setting collision response type
TriggerBox ->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryOnly);

//setting collision response by specific channel
//you can override individual channel responses within your existing profile, or set specific responses for every
//available channel in your game

//this first line strips any preset collision responses and sets the component to ignore all
TriggerBox ->BodyInstance.SetResponseToAllChannels(ECR_Ignore);

//you can set individual response types for the channels you want; ECR_Overlap, ECR_Block, or ECR_Ignore
//in this case all are set to trigger overlaps
TriggerBox ->BodyInstance.SetResponseToChannel(ECC_WorldStatic, ECR_Overlap);
TriggerBox ->BodyInstance.SetResponseToChannel(ECC_WorldDynamic, ECR_Overlap);
TriggerBox ->BodyInstance.SetResponseToChannel(ECC_Pawn, ECR_Overlap);
TriggerBox ->BodyInstance.SetResponseToChannel(ECC_PhysicsBody, ECR_Overlap);
TriggerBox ->BodyInstance.SetResponseToChannel(ECC_Vehicle, ECR_Overlap);
TriggerBox ->BodyInstance.SetResponseToChannel(ECC_Destructible, ECR_Overlap);

You can build the component’s channel response to respond differently to different channels, as well as create your own custom channels and collision profiles.

You can also set these values in the editor within the details panel of your object, under Collision and the Collision Presets panel.

For more details see:

Default collision channels and response types are defined in ‘Runtime/Engine/Classes/Engine/EngineTypes.h’; see lines 553 and 743.

UCollisionProfiles are defined in ‘Runtime/Engine/Classes/Engine/CollisionProfile.h’

Thanks but in my case it was just simply recreating the assset whjch helps

You are a [redacted] genius. Solved my problem too!

Since you are using AddDynamic Binding in constructor which is called initially.You have to do in begin play.

1 Like

I have been trying to figure this out for weeks, off and on, I can’t believe this is the solution and still in 4.21. Insane, but thank you.

Thanks man. This solved my issue. They should fix this in the engine.

In my case re-creating the BP was not enough. Had to close the editor, rebuild in the IDE, relaunch the editor and create the BP again. Then it worked.

Thanks!

I know this issue has been closed but I want to clarify one mistake in the code which @FinalRockstar also touched upon: Never add any bindings in the C++ class’ constructor.

Anything that happens in the constructor gets serialized into the asset itself, which is why people often have to recreate the assets when changing these bindings for those changes to take effect. In this case, the function binding is literally getting serialized and saved into the TriggerBox->OnComponentBeginOverlap property.

The C++ constructor should ONLY be used to set up the object, its subobjects and defaults, and nothing else. Any other initialization like event bindings you should do in BeginPlay(). (there are also some initialization you can defer until PostLoad(), but event bindings should not go there either)

1 Like

Thanks. That was the answer that solved my problem.