How to get onhit events to fire with collisions?

I’m not sure if you got this fixed or not but for me it is a little misleading. I prefer that any mesh, sound, collision components to be set in the BP without any requirements for the C++ side of things. After all that’s the beauty of the integration between C++ and BP. And I’ve run into this exact problem.

Have you tried:

For the bullet:



.h
    UFUNCTION()
    void OnHit(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit);

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = Movement)
    UProjectileMovementComponent* ProjectileMovement;


.cpp
AMyBullet::AMyBullet(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
    ProjectileMovement = ObjectInitializer.CreateDefaultSubobject<UProjectileMovementComponent>(this, TEXT("Movement"));
    ProjectileMovement->UpdatedComponent = RootComponent;

    OnActorHit.AddDynamic(this, &AMyBullet::OnHit);

    InitialLifeSpan = 30.0f;
    PrimaryActorTick.bCanEverTick = true;
}


void AMyBullet::SetInitVelocity(const FVector& ShootDirection)
{
    if (ProjectileMovement)
    {
        ProjectileMovement->Velocity = ShootDirection * ProjectileMovement->InitialSpeed;
    }
}


void AMyBullet::OnHit(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit)
{
    FColor DisplayColor = FColor::Yellow;
    const FString DebugMessage(OtherActor->GetName());
    GEngine->AddOnScreenDebugMessage(-1, 5.0f, DisplayColor, DebugMessage);

    if (OtherActor)
    {
        if (OtherActor->IsA(APawn::StaticClass()))
        {
            APawn* Pawn(Cast<APawn>(OtherActor));
            if (Pawn)
            {
                float DamageAmount = 600.0f;
                const FDamageEvent DamageEvent;
                AController* EventInstigator = nullptr;
                AActor* DamageCauser = this;

                Pawn->TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
            }
        }
    }

    Destroy();
}


For an actor/pawn:



.h
    UFUNCTION()
    void OnHit(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit);

.cpp
AMyPawn::AMyPawn(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
    PrimaryActorTick.bCanEverTick = true;
    OnActorHit.AddDynamic(this, &AMyPawn::OnHit);
}


void AMyPawn::OnHit(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit)
{
    FColor DisplayColor = FColor::Yellow;
    const FString DebugMessage(OtherActor->GetName());
    GEngine->AddOnScreenDebugMessage(-1, 5.0f, DisplayColor, DebugMessage);

    if (OtherActor)
    {
        if (OtherActor->IsA(ABullet::StaticClass()))
            Destroy();
    }
}


This is still very much a work-in-progress that I am sharing incase it helps in some way.

The little OnActorHit.AddDynamic() was found here:

And a really nice projectile walkthrough is here:

Btw, while running the game press ~, then enter “show collision” to see the collision boxes.

1 Like