I want to do something when the player overlaps a door switch (AActor). If an enemy overlaps the door switch, nothing happens.
void ADSDoorSwitch::OnComponentBeginOverlap(
UPrimitiveComponent* OverlappedComponent,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex,
bool bFromSweep,
const FHitResult& SweepResult)
{
if (ATopDownCharacter* TopDownCharacter = Cast<ATopDownCharacter>(OtherActor))
{
// I'm going to do nothing with TopDownCharacter.
// I just want to check it OtherActor is the Player.
// It's a single player game,
// so there is only one ATopDownCharacter instance.
}
}
Using the class ATopDownCharacter, (I think) I’m creating a dependency between this class and ADSDoorSwitch.
Is there a way to do it without using the class ATopDownCharacter? With an Interface? Or just using ACharacter?
#include "GameFramework/PlayerController.h"
if (APlayerController* PC = GetWorld()->GetFirstPlayerController())
{
if (OtherActor == PC->GetPawn())
{
// Player overlapped
}
}
#include "Kismet/GameplayStatics.h"
PlayerPawn = UGameplayStatics::GetPlayerPawn(this, 0);
if (OtherActor == PlayerPawn)
{
// Player overlapped
}
#include "GameFramework/Pawn.h"
if (APawn* Pawn = Cast<APawn>(OtherActor))
{
if (Pawn->IsPlayerControlled())
{
// Player overlapped
}
}
Its better to use an Interface and GameplayTags in my opinion, this way you can create an overlap component and reuse it with anything by just changing the required Tag
so you can filter with a custom collision channel like interactable
then on your interactables have a GameplayTagContainer, since interactables could be anything, actor/character/enemy etc use an interface to GetGameplayTags or HasGameplayTag
then all you have to do is on overlap does actor have Tag Interactable.Player or something
Well, I only code with blueprints right now since I am new to this and have no programming background, aside of some python, but I did it with interfaces. In the door’s BP, on actor overlap, checked if other actor implements interface and call the interface function. That’s assuming it’s an automatic itneraction, if it’s manual it’s the other way around (the character checks if the door implements the BPI).
The often-repeated advice about avoiding casts because they create hard asset references only applies to blueprint classes, not c++.
From a software engineering perspective, checks for specific classes like this aren’t ideal for extensibility, but you don’t need some sort of extendable player character interface tag whatever thing if you only have one type of player character!
Whether or not being free of dependencies is important depends on who you talk to. I’m going to trust my instincts on this one and continue to be concerned about not having dependencies.
if (APawn* Pawn = Cast<APawn>(OtherActor))
{
if (Pawn->IsPlayerControlled())
{
// You need a dependency to APawn in this case
}
}
AActor has no notion of “players” so it is impossible to check anything about the player if you don’t have either a dependency to a class that knows about players (APawn) or have some additional data added (a gameplay tag)