I have been attempting to get a basic implementation of the AI Perception System working with no luck. I have an AI Perception Stimuli Source Component on my player Character with bAutoRegisterForSenses set to true and AISense_Sight and AISense_Hearing added to RegisterAsSourceForSenses. I also have an AI Perception Component on my AI Controller with AISenseConfig_Hearing and AISenseConfig_Sight added to the SensesConfig array, both set to detect enemies, neutrals, and friendlies. In my AI Controller I have a function called OnPerceptionUpdated, which I bind to the Perception Component’s OnTargetPerceptionInfoUpdated in BeginPlay. The OnPerceptionUpdated function just contains a log statement. However, when I run the game and move my character in front of one of the AI character’s nothing is printed. I also don’t see anything when I turn on the debug view by pressing the apostrophe key, followed by Numpad-4.
MyAIController.h
UCLASS()
class MYPROJECT_API AMyAIController : public AAIController
{
GENERATED_BODY()
public:
AMyAIController();
protected:
virtual void BeginPlay() override;
public:
UFUNCTION()
void OnPerceptionUpdated(const FActorPerceptionUpdateInfo& UpdateInfo);
};
MyAIController.cpp
AMyAIController::AMyAIController()
{
PrimaryActorTick.bCanEverTick = true;
PerceptionComponent = CreateDefaultSubobject<UMyPerceptionComponent>(TEXT("PerceptionComponent"));
}
void AMyAIController::BeginPlay()
{
Super::BeginPlay();
if (PerceptionComponent)
{
PerceptionComponent->OnTargetPerceptionInfoUpdated.AddDynamic(this, &AMyAIController::OnPerceptionUpdated);
}
}
void AMyAIController::OnPerceptionUpdated(const FActorPerceptionUpdateInfo &UpdateInfo)
{
FString DebugString = UpdateInfo.Stimulus.GetDebugDescription();
FString ActorName = UpdateInfo.Target.IsExplicitlyNull() ? FString("InvalidTarget") : UpdateInfo.Target->GetActorNameOrLabel();
UE_LOG(LogController, Display, TEXT("MyAIController:: Stimulus: %s from %s"), *DebugString, *ActorName);
}
MyPerceptionComponent.h
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYPROJECT_API UMyPerceptionComponent : public UAIPerceptionComponent
{
GENERATED_BODY()
public:
UMyPerceptionComponent(const FObjectInitializer &ObjectInitializer);
};
MyPerceptionComponent.cpp
UMyPerceptionComponent::UMyPerceptionComponent(const FObjectInitializer& ObjectInitializer) :
UAIPerceptionComponent(ObjectInitializer)
{
TObjectPtr<UAISenseConfig_Hearing> HearingConfig = CreateDefaultSubobject<UAISenseConfig_Hearing>(TEXT("HearingConfig"));
TObjectPtr<UAISenseConfig_Sight> SightConfig = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("SightConfig"));
CHECK_NULLPTR_RET(HearingConfig, LogAIPerception, "MyPerceptionComponent:: Failed to create SenseConfig_Hearing");
HearingConfig->DetectionByAffiliation.bDetectFriendlies = true;
HearingConfig->DetectionByAffiliation.bDetectEnemies = true;
HearingConfig->DetectionByAffiliation.bDetectNeutrals = true;
HearingConfig->SetMaxAge(5.0f);
CHECK_NULLPTR_RET(SightConfig, LogAIPerception, "MyPerceptionComponent:: Failed to create SenseConfig_Sight");
SightConfig->DetectionByAffiliation.bDetectFriendlies = true;
SightConfig->DetectionByAffiliation.bDetectEnemies = true;
SightConfig->DetectionByAffiliation.bDetectNeutrals = true;
SightConfig->SetMaxAge(5.0f);
SightConfig->PeripheralVisionAngleDegrees = 60;
SightConfig->PointOfViewBackwardOffset = 100.0f;
SightConfig->NearClippingRadius = 100.0f;
SensesConfig.Append({HearingConfig, SightConfig});
}
MyStimuliSourceComponent.h
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYPROJECT_API UMyStimuliSourceComponent: public UAIPerceptionStimuliSourceComponent
{
GENERATED_BODY()
public:
UMyStimuliSourceComponent(const FObjectInitializer &ObjectInitializer);
protected:
virtual void OnRegister() override;
};
MyStimuliSourceComponent.cpp
UMyStimuliSourceComponent::UMyStimuliSourceComponent(const FObjectInitializer& ObjectInitializer) :
UAIPerceptionStimuliSourceComponent(ObjectInitializer)
{
bAutoRegisterAsSource = true;
RegisterAsSourceForSenses.Append({UAISense_Sight::StaticClass(), UAISense_Hearing::StaticClass()});
}
void UMyStimuliSourceComponent::OnRegister()
{
Super::OnRegister();
FString Senses = "";
for (auto& SenseClass : RegisterAsSourceForSenses)
{
Senses.Append(SenseClass.Get()->GetName() + ", ");
}
UE_LOG(LogTemp, Display, TEXT("MyStimuliSourceComponent:: Successfully registered for %s"), *Senses);
}
Does anyone know what I’m missing? This is my first time trying to use the Perception System and I can’t find any c++ tutorials for it. Every tutorial I’ve found is 100% done in blueprints. I thought I’d done the equivalent of everything they did in c++, but it just isn’t working at all.