ActorBeginOverLap C++

I’m trying to get collision set up within my game for when the enemy overlaps the player they take damage.

I’ve got it setup so far that the Player can take damage when entering the ‘Collision Box’ of the enemy via blueprint. The Player uses the TakeDamage function in C++ and works with no issues.
I’ve got the Event ActorBeginOverlap node connected to the ApplyDamage node which works perfectly.
I’m now trying to translate this into C++ rather then BP.

So far, I have this in the Actor that will be dealing the damage to the player.
BasicZombie.h

UPROPERTY(VisibleAnywhere, Category = BoxCollision)
     UBoxComponent* BoxCollider;

BasicZombie.cpp

ABasicZombie::ABasicZombie()
{
    BoxCollider = CreateDefaulySubobject<UBoxComponent>(TEXT("BoxCollider");
    BoxCollider->GetScaledBoxExtent();
    BoxCollider->SetupAttachment(RootComponent);
}

I have been searching around and a few different websites have said to use either OnActorBeginOverlap or OnComponentBeginOverlap and then use the AddDynamic function. However, the AddDynamic() function doesn’t exist only Add or AddUnique . Is there a new way of doing this in C++?

It’s not a function. It’s a macro that calls __Internal_AddDynamic

BoxCollider->OnActorBeginOverlap.AddDynamic(this, &ABasicZombie::ApplyDamage);

Is actually

BoxCollider->OnActorBeginOverlap.__Internal_AddDynamic(this, &ABasicZombie::ApplyDamage, UE4Delegates_Private::GetTrimmedMemberFunctionName(TEXT("&ABasicZombie::ApplyDamage")));

And GetTrimmedMemberFunctionName just gets the function name without the class prefix and &. so altogether it’s the same as

BoxCollider->OnActorBeginOverlap.__Internal_AddDynamic(this, &ABasicZombie::ApplyDamage, TEXT("ApplyDamage"));

Doing BoxCollider-> doesn’t show OnActorBeginOverlap. This only appears without the BoxCollider->.

That was just an example showing that AddDynamic isn’t a member function. I didn’t pay to much attention to the type of BoxCollider, sorry. OnActorBeginOverlap doesn’t exist because it’s not an actor, the component version should exist though.

OnComponentBeginOverlap does exsit yes.
The ABasicZombie is an actor, or do you mean that BoxCollider isn’t an actor?
If that’s the case, how would I go about using AddDynamic() to deal damage to the AMainCharacter class?

I meant this.


By calling take damage on it within the function you’re using for AddDynamic.

Sorry to be a nusence, I’m not understanding what I’m meant to do based on your replies.

Sorry I assumed you were following a tutorial or similar and got a little stuck and could continue after.

If you want to translate your blueprint directly:

Declare the following function

UFUNCTION()
void DamageOnOverlap(AActor* OverlappedActor, AActor* OtherActor);

Then implement it

ABasicZombie::DamageOnOverlap(AActor* OverlappedActor, AActor* OtherActor)
{
    // second arg is damage amount
	UGameplayStatics::ApplyDamage(OverlappedActor, 10.f, GetController(), this, UDamageType::StaticClass());
}

(I may have messed up which actor to use for apply damage)

The binding is then just

OnActorBeginOverlap.AddDynamic(this, &ABasicZombie::DamageOnOverlap);

That seems to be working, no compiler errors! However, when I go into game and overlap the MainCharcater with the BasicZombie, the MainCharacter does not take any damage. In this instance, BasicZombie should be dealing damage to MainCharacter.

I’m not sure if it’s to do with the third arugment in the AppleDamage function. I have done GetControlle(), but it says it is undefined. I have included the correct header file from the UE4 documentation, but no luck. I have even tried APawn::GetController() and no luck.

Is the function even being called (add logs)? Where did you do the AddDynamic? And did you make a blueprint before adding that code?

The function doesn’t seem to be being called when they overlap.

In the BasicZombie.h, I’ve got the following

UFUNCTION()
    void DamageOnOverlap(AActor* OverlappedActor, AActor* OtherActor);

BasicZombie.cpp has the following

void ABasicZombie::DamageOnOverlap(AActor* OverlappedActor, AActor* OtherActor)
{
    GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, TEXT("[BasicZombie Debug] - Overlapped!"));
    UGameplayStatics::ApplyDamage(OverlappedActor, 25.0f, GetWorld()->GetFirstPlayerController(), this, UDamageType::StaticClass());
    OnActorBeginOverlap.AddDynamic(this, &ABasicZombie::DamageOnOverlap);
}

With the blueprint, this is all done in the BasicZombie BP.
bp
With the BP currently, this works just by having these two nodes linked up.

Edit: I realised a small mistake, I was trying to call the function within the function, hense why it was never being called, so I have removed the OnActorBeginOverlap. However, the damage doesn’t seem to apply to the MainCharacter when overlapped.

This should be in the constructor, though if you already created a blueprint of this class you would need to use BeginPlay. Also judging by the blueprint equivalent I suppose the second parameter is what should be used for ApplyDamage.

I did spot that small error before hand. I edited my previous post.

The actors are now overlapping correctly with a debug message appearing on screen. However, MainCharacter does not get damaged when they overlap.

Are you applying it to the right actor?

GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, FString::Printf(TEXT("[BasicZombie Debug] - Overlapped is %s, Other is %s", *OverlappedActor->GetName(), *OtherActor->GetName()));

Using that line of code returns BP_BasicZombie_2 and BP_MainCharacter_C_0. By the looks of it, GetWorld()->GetFirstPlayerController() might be the issue as when they overlap, MainCharacter is dealing damage, rather than the opposite way around.

Did you correct the code as suggested?

Sorry, I don’t understand what you mean by that.
Do you mean the ApplyDamage function in the DamageOnOverlapp function?

UGameplayStatics::ApplyDamage(OverlappedActor, 10.f, GetController(), this, UDamageType::StaticClass());
//                              ^^^ change this to OtherActor

That works perfectly! Thank you so much for all of your help!

I do have one last question, as I’m using GetWorld()->GetFirstPlayerController() is that different from GetController()? I have tried to use GetController(), but it says it is undefined.

I assumed ABasicZombie would be a Pawn. That is where GetController() is defined.

Yes. The purpose of that parameter is for the controller that dealt the damage which the first player controller wouldn’t be here. You can pass in nullptr if no controller was responsible for the damage (think explosive barrel, large rock falling) but as yours says “Zombie” it sounds like that should be a pawn. Is it not going to be controlled by AI?

Privacy & Terms