How to setup AI Perception

So I know that there are a couple of tutorials coming up on how to use the new AI Perception System. I can’t wait to really dig in and start using it, but seeing as those aren’t out yet (any idea when one will be up?) I was wondering if anyone knows how to do a simple setup for it to do some simple sensing. This is what I’ve gotten so far but I seem to be missing something:

First inside of my controller (Constructor) I setup my function that will do stuff when I see something:

PerceptionComponent->OnPerceptionUpdated.AddDynamic(this, &AAIControllerUnit::SenseStuff);

Next also inside of my controller (OnPossess) I configure my sight sense:

// Setup the perception component
sightConfig->SightRadius = possessedUnit->sightRange;
sightConfig->LoseSightRadius = (possessedUnit->sightRange + 20.0f);
sightConfig->PeripheralVisionAngleDegrees = 360.0f;
PerceptionComponent->ConfigureSense(*sightConfig);

Next I register my pawn as a stimuli source so that I can detect it (also in OnPossess):

// Setup the controlled pawn as a stiumuli source for the Perception System
UAIPerceptionSystem::RegisterPerceptionStimuliSource(this, sightConfig->GetSenseImplementation(), GetControlledPawn());

Now in the Tick() of the controller i do this:

PerceptionComponent->RequestStimuliListenerUpdate();

Finally my sense stuff function inside of the controller:

void AAIControllerUnit::SenseStuff(TArray<AActor*> testActors)
{
	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "I see you!");
}

I think i’m close to figuring it out but i’m missing something key (or maybe I should just wait for a tutorial haha). Essentially the SenseStuff function is never getting called when two of my units that are using this get close to each other.

Thanks in advance!
-Chris

Hey Chris,

First of all, this bit:

PerceptionComponent->RequestStimuliListenerUpdate();

don’t do it :slight_smile: This usually gets called under the hood to modify navigation system that perception listener’s properties has changed, like hearing radius, team, senses used, and such.

If this doesn’t help try configuring your sight to “see all affiliations”, like so:

sightConfig->DetectionByAffiliation.bDetectEnemies = true;
sightConfig->DetectionByAffiliation.	bDetectNeutrals = true;
sightConfig->DetectionByAffiliation.bDetectFriendlies = true;

There are still some bugs or missing convenience featured in perception system so please report anything you find. And let me know if what I said helped, of course :smiley:

Cheers,

–mieszko

Ahh ok thanks! That got it to work in a bar bones project so I can go from there now. My current project is still having issues even with the changes, but I think its something else on my end causing trouble so once I figure that out it should work.

Thanks again!

-Chris

I currently have the same problem.

This is my header:

    UAIPerceptionComponent* PerceptionComp;
    
    class UAISenseConfig_Sight* Sight;
    
    void UpdatePerception(TArray<AActor*> SensedActor);

This is my CPP:

AAICtrl_Collector::AAICtrl_Collector(const class FObjectInitializer& ObjectInitializer)
	:Super(ObjectInitializer)
{
	// Initialize de Perception components
	PerceptionComp = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("AIPerception Component"));
	Sight = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("Sight Config"));

	// Sight configuration
	Sight->SightRadius = 500;
	Sight->LoseSightRadius = 600;
	Sight->PeripheralVisionAngleDegrees = 180.0f;
	Sight->DetectionByAffiliation.bDetectEnemies = true;
	Sight->DetectionByAffiliation.bDetectNeutrals = true;
	Sight->DetectionByAffiliation.bDetectFriendlies = true;

	// Apply Sight to Perception Component
	PerceptionComp->ConfigureSense(*Sight);
	PerceptionComp->SetDominantSense(Sight->GetSenseImplementation());

        // Binds event to sense other actors
	PerceptionComp->OnPerceptionUpdated.AddDynamic(this, &AAICtrl_Collector::UpdatePerception);

void AAICtrl_Collector::UpdatePerception(TArray<AActor*> SensedActor)
{
	UE_LOG(LogTemp, Warning, TEXT("I can see!"));
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Blue, "I can see!");
}

None of the messages I put in UpdatePerception are printed to the output log. I debugged the code and the UpdatePerception function is never called. Am I missing anything?

I had the same problem. Calling this function in the BeginPlay() looks like the solution:

UAIPerceptionSystem::RegisterPerceptionStimuliSource(this, UAISense_Sight::StaticClass(), this);

I have this in MyAiController, as that’s where my PerceptionComponent is located.

However it worked for me before without this, and then it just stopped, so idk, looks like kinda weird for me, and I couldn’t find any material explaining how should I do what. So I am just playing with the functions and debugging the results.

One thing that I think is really strange is that when I simulate the game and select the actor, it highlights the other one like it detected the other actor.

So, I think my issue might be just on my delegate function.

I got it working! I just missed a “UFUNCTION()” above “void UpdatePerception(TArray SensedActor);” in the header file.