I can't seem to get the Perception System working at all.

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.

Do you call ConfigureSense() anywhere? I have this in a working program:

AIPerceptionComponent = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("PerceptionComponent"));
AISenseConfig_Sight = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("Sight Config"));
AIPerceptionComponent->ConfigureSense(*AISenseConfig_Sight);

Do you see anything in the output log?

I tried adding calls to ConfigureSense for both Sight and Hearing, but I’m still not seeing anything in the log.

The logs just weren’t showing up because I was using the LogController category. Not sure why that doesn’t appear in the output log, but when I switched to LogTemp they started appearing as expected.