I created a specific C++ class for my projectile:
ABasicProjectile::ABasicProjectile()
{
CollisionComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
CollisionComp->InitSphereRadius(500.0f); // Increase to 20.0f for test
CollisionComp->OnComponentBeginOverlap.AddDynamic(this, &ABasicProjectile::OnOverlapBegin);
CollisionComp->OnComponentHit.AddDynamic(this, &ABasicProjectile::OnHit);
RootComponent = CollisionComp;
SetRootComponent(CollisionComp);
ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileComp"));
ProjectileMovement->UpdatedComponent = CollisionComp;
ProjectileMovement->InitialSpeed = 3000.0f;
ProjectileMovement->MaxSpeed = 3000.0f;
ProjectileMovement->bRotationFollowsVelocity = true;
ProjectileMovement->bShouldBounce = false;
ProjectileMovement->ProjectileGravityScale = 0.0f;
SetLifeSpan(3.0f);
}
with onHit and OnOverlapBegin:
void ABasicProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
UE_LOG(LogTemp, Warning, TEXT("Projectile OnHit triggered with %s"), *OtherActor->GetName());
if (OtherActor && OtherActor != this && OtherActor != GetInstigator() && OtherComp)
{
UHealthComponent* HealthComp = OtherActor->FindComponentByClass<UHealthComponent>();
if (HealthComp)
{
UE_LOG(LogTemp, Warning, TEXT("HealthComp found on %s, applying %f damage"), *OtherActor->GetName(), Damage);
HealthComp->TakeDamage(Damage);
}
else {
UE_LOG(LogTemp, Error, TEXT("No HealthComp on %s"), *OtherActor->GetName());
}
}
Destroy();
}
void ABasicProjectile::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
UE_LOG(LogTemp, Warning, TEXT("Projectile OnOverlap triggered with %s"), *OtherActor->GetName());
if (OtherActor && OtherActor != this && OtherActor != GetInstigator() && OtherComp)
{
UHealthComponent* HealthComp = OtherActor->FindComponentByClass<UHealthComponent>();
if (HealthComp)
{
UE_LOG(LogTemp, Warning, TEXT("HealthComp found on %s, applying %f damage"), *OtherActor->GetName(), Damage);
HealthComp->TakeDamage(Damage);
}
else {
UE_LOG(LogTemp, Error, TEXT("No HealthComp on %s"), *OtherActor->GetName());
}
Destroy();
}
}
I also have proper collision in the Blueprint setup:
With all this setup, I have no logs from my events.
I have a similar setup between other components, where it looks fine, but I used:
GetCapsuleComponent()->OnComponentBeginOverlap.AddDynamic(this, &AMainEnemy::OnOverlapBegin);
So I assume the issue may be related to how CreateDefaultSubobject works; I am not sure.