Hi!
I want to use the AIPerceptionComponent with multiple AISenseConfig. I want to be able to make different actions depending on which sense is triggered.
For now I’m able to trigger Damage and hearing events but the sight dont work. It works with the same code alone in his own AIPerceptionComponent but not with two others.
Is it a good practice to have multiple AIPerceptionComponent on the same Controller to separate sense?
At same time, I was wondering what it is the best practice to differentiate between the senses
#include "CivilianAIController.h"
#include "Kismet/GameplayStatics.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "CivilianCharacter.h"
#include "Perception/AIPerceptionComponent.h"
#include "Perception/AISenseConfig_Sight.h"
#include "Perception/AISenseConfig_Hearing.h"
#include "Perception/AISenseConfig_Damage.h"
ACivilianAIController::ACivilianAIController(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
PerceptionComponent = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("AIHearing Component"));
SightConfig = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("Sight Config"));
HearingConfig = CreateDefaultSubobject<UAISenseConfig_Hearing>(TEXT("Hearing Config"));
DamageConfig = CreateDefaultSubobject<UAISenseConfig_Damage>(TEXT("Damage Config"));
PerceptionComponent->ConfigureSense(*SightConfig);
PerceptionComponent->ConfigureSense(*HearingConfig);
PerceptionComponent->ConfigureSense(*DamageConfig);
PerceptionComponent->SetDominantSense(SightConfig->GetSenseImplementation());
PerceptionComponent->OnTargetPerceptionUpdated.AddDynamic(this, &ACivilianAIController::TargetPerceptionUpdated);
}
void ACivilianAIController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
if (SightConfig && PerceptionComponent)
{
SightConfig->SightRadius = SightRadius;
SightConfig->LoseSightRadius = LoseSightRadius;
SightConfig->PeripheralVisionAngleDegrees = PeripheralVisionDegrees;
SightConfig->DetectionByAffiliation.bDetectEnemies = true;
SightConfig->DetectionByAffiliation.bDetectNeutrals = true;
SightConfig->DetectionByAffiliation.bDetectFriendlies = true;
PerceptionComponent->ConfigureSense(*SightConfig);
}
if (HearingConfig && PerceptionComponent)
{
HearingConfig->HearingRange = AIHearingRange;
HearingConfig->DetectionByAffiliation.bDetectEnemies = true;
HearingConfig->DetectionByAffiliation.bDetectNeutrals = true;
HearingConfig->DetectionByAffiliation.bDetectFriendlies = true;
PerceptionComponent->ConfigureSense(*HearingConfig);
}
}
void ACivilianAIController::BeginPlay()
{
Super::BeginPlay();
if (AIBehavior)
{
PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
RunBehaviorTree(AIBehavior);
GetBlackboardComponent()->SetValueAsVector(TEXT("StartLocation"), GetPawn()->GetActorLocation());
}
}
void ACivilianAIController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ACivilianAIController::TargetPerceptionUpdated(AActor* Actor, FAIStimulus Stimulus)
{
UAISenseConfig* SenseUpdated = PerceptionComponent->GetSenseConfig(Stimulus.Type);
if (SenseUpdated)
{
if (SenseUpdated->GetClass() == HearingConfig->GetClass())
{
UE_LOG(LogTemp, Warning, TEXT("Pawn hearded in PerceptionUpdated"));
}
else if (SenseUpdated->GetClass() == SightConfig->GetClass())
{
UE_LOG(LogTemp, Warning, TEXT("Pawn saw in PerceptionUpdated"));
}
else if (SenseUpdated->GetClass() == DamageConfig->GetClass())
{
UE_LOG(LogTemp, Warning, TEXT("Pawn damaged in PerceptionUpdated"));
}
}
}
Header:
#pragma once
#include "CoreMinimal.h"
#include "AIController.h"
#include "Perception/AIPerceptionTypes.h"
#include "CivilianAIController.generated.h"
/**
*
*/
UCLASS()
class SAMPLESHOOTERREMIX_API ACivilianAIController : public AAIController
{
GENERATED_BODY()
public:
ACivilianAIController(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
virtual void Tick(float DeltaTime) override;
bool IsDead() const;
UFUNCTION()
void TargetPerceptionUpdated(AActor* Actor, FAIStimulus Stimulus);
protected:
virtual void OnPossess(APawn* InPawn) override;
virtual void BeginPlay() override;
class UAIPerceptionComponent* PerceptionComponent;
//class UAIPerceptionComponent* SightPerceptionComponent;
class UAISenseConfig_Sight* SightConfig;
class UAISenseConfig_Hearing* HearingConfig;
class UAISenseConfig_Damage* DamageConfig;
private:
UPROPERTY(EditAnywhere)
class UBehaviorTree* AIBehavior;
APawn* PlayerPawn;
UPROPERTY(EditDefaultsOnly)
float SightRadius;
UPROPERTY(EditDefaultsOnly)
float LoseSightRadius;
UPROPERTY(EditDefaultsOnly)
float PeripheralVisionDegrees;
UPROPERTY(EditDefaultsOnly)
float AIHearingRange;
};