I made a simple pawn class that's supposed to be a ball and move around and collect coins. For the coin collection system I made the on overlap event to notify the ball when it is hit. Here is the basic code (APlayerBall is the default pawn class that gets spawned into the game) :
PlayerBall.h
UCLASS()
class ROLLINGBALL_API APlayerBall : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
APlayerBall();
UPROPERTY(VisibleAnywhere, Category="Mesh")
UStaticMeshComponent* Mesh;
UPROPERTY(VisibleAnywhere, Category="Mesh")
class UCameraComponent* Camera;
UPROPERTY(VisibleAnywhere, Category="Mesh")
class UCapsuleComponent* Capsule;
protected:
// Called when the game starts or when spawned
void BeginPlay() override;
UFUNCTION()
void BeginOverlap(UPrimitiveComponent* OverlappedComponent,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex,
bool bFromSweep,
const FHitResult &SweepResult );
public:
// Called every frame
void Tick(float DeltaTime) override;
// Called to bind functionality to input
void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
PlayerBall.cpp
Constructor:
APlayerBall::APlayerBall() {
Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
Mesh->SetStaticMesh(ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere'")).Object);
Mesh->SetSimulatePhysics(true);
Mesh->SetEnableGravity(true);
SetRootComponent(Mesh);
Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
Camera->SetRelativeLocation(FVector(-500.0f, 0.0f, BaseEyeHeight));
Camera->SetupAttachment(RootComponent);
Capsule = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule"));
Capsule->OnComponentBeginOverlap.AddDynamic(this, &APlayerBall::BeginOverlap);
Capsule->SetupAttachment(Mesh);
AutoPossessPlayer = EAutoReceiveInput::Player0;
}
And the BeginOverlap
method:
void APlayerBall::BeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) {
UE_LOG(LogTemp, Warning, TEXT("%s"), *OtherActor->GetHumanReadableName());
UE_LOG(LogTemp, Warning, TEXT("%s"), *GetHumanReadableName());
UE_LOG(LogTemp, Warning, TEXT("%s"), OtherActor == this ? TEXT("The Colliding Actor Is Myself") : TEXT("The Colliding Actor Is Not Myself"));
}
As you can see, I added logging messages to see what exactly is hitting it. After a little bit of debugging, I found that it is getting hit by itself for some reason. As soon as the game starts, the logging screen looks like this: Why is this happening? How can I fix this?
It looks like the mesh component is overlapping with the capsule component. Add the component to your logs to confirm.
If you only want to know when your actor overlaps with another actor, you might want to use AActor::NotifyActorBeginOverlap
instead.
If you want to use component overlaps, but you want to ignore overlaps of other components in your own actor, then you'll either have to filter them out yourself in BeginOverlap
or adjust your physics collision profiles so that each component has a different object type that do not generate overlap events for each other. If it were me, I'd just do a filter like so:
void APlayerBall::BeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) {
if (this == OtherActor) {
// The Colliding Actor Is Myself. Ignoring because I don't care about this for some reason.
UE_LOG(LogTemp, Warning, TEXT("Ignoring component overlap of my own components"));
return;
}
UE_LOG(LogTemp, Warning, TEXT("%s"), *OtherActor->GetHumanReadableName());
UE_LOG(LogTemp, Warning, TEXT("%s"), *GetHumanReadableName());
}