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.