First off all they need to be override the base class to be called and second I think that OnPerceptionUpdated and OnTargetPerceptionUpdated are blueprint events not available in cpp. A function very similar is ActorsPerceptionUpdated().
I recommend configuring your sight before setting the perception component like this , you can use the same code in your " OnPossess" function
YourController::YourController() {
AIPerceptionComponent = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("AIPerceptionComponent"));
// Create Sight configuration for the AIPerception component
UAISenseConfig_Sight* SightConfig = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("SightConfig"));
SightConfig->SightRadius = 1000.0f; // Set your sight radius
SightConfig->LoseSightRadius = 1200.0f; // Set your lose sight radius
SightConfig->PeripheralVisionAngleDegrees = 180.0f; // Set your peripheral vision angle
SightConfig->SetMaxAge(0.0f); // Set your max age, 0.0f means never expires
// detect friendly pawns
SightConfig->DetectionByAffiliation.bDetectEnemies = true;
SightConfig->DetectionByAffiliation.bDetectFriendlies = true;
SightConfig->DetectionByAffiliation.bDetectNeutrals = true;
// Register the sight configuration with the AIPerception component
AIPerceptionComponent->ConfigureSense(*SightConfig);
// Set the AIPerception component
SetPerceptionComponent(*AIPerceptionComponent);
// Bind your functions to the delegates
GetPerceptionComponent()->OnPerceptionUpdated.AddDynamic(this, &YourController::ActorsPerceptionUpdated);
GetPerceptionComponent()->OnTargetPerceptionUpdated.AddDynamic(this, &YourController::TargetActorsPerceptionUpdated);
}
void YourController::TargetActorsPerceptionUpdated(AActor* TargetActor, FAIStimulus Stimulus)
{
if (TargetActor->ActorHasTag("Player")) {
if (Stimulus.WasSuccessfullySensed()) {
// Player is currently seen
UE_LOG(LogTemp, Warning, TEXT("I see you!"));
} else {
// Player was last seen
FVector LastSeenLocation = Stimulus.StimulusLocation;
UE_LOG(LogTemp, Warning, TEXT("I last saw you at: %s"), *LastSeenLocation.ToString());
}
}
}
void YourController::ActorsPerceptionUpdated(const TArray<AActor*>& UpdatedActors) {
// Iterate through updated actors
for (int32 i = 0; i < UpdatedActors.Num(); i++) {
// Check if the updated actor is the player
if (UpdatedActors[i]->ActorHasTag("Player")) {
// Log a message for testing
UE_LOG(LogTemp, Warning, TEXT("I see you!"));
}
}
}
also make sure you configured your stimuli source component in your Character class constructor or any other Actor that you want the perception system to detect. Sight is just an example in the snippet below, you can register more senses, i suggest testing it in blue prints first and then use it in code
// set up stimulus source component in your Character class for example
UAIPerceptionStimuliSourceComponent* StimuliSourceComponent = CreateDefaultSubobject<UAIPerceptionStimuliSourceComponent>(TEXT("StimulusSourceComponent"));
// Set the custom tag
StimuliSourceComponent->ComponentTags.Add(FName("Player"));
StimuliSourceComponent->RegisterForSense(TSubclassOf<UAISense_Sight>());
StimuliSourceComponent->RegisterWithPerceptionSystem();
You should be able to successfully sense registered stimuli after making these changes.
OnPerceptionUpdated and OnTargetPerceptionUpdated are delegates in AIPerceptionComponent.h, they are available in cpp, you can bind them to your cpp functions, see the snippets below