Quick AI Perception Jumpstart (C++)

So seeing as there aren’t any tutorials for this yet (I know there are some upcoming that will be more in depth) I thought I would share a bit of how to setup the AI Perception Component for anyone who wants to get a head start and start messing around with it. You can also find my blueprint version of this here:

(This is done with version 4.7.5)
These are the first and probably most important things you need to do. First create the perception component. Next you want to create a config for any senses you may want to use and add them to the component with ConfigureSense() Next you can set the sense that will override other senses. Finally you bind a function to be called when the Perception System gets a stimuli (ie. sees or hears something).

// Setup the perception component
PerceptionComponent = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("AIPerception Component"));
sightConfig = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("Sight Config"));
PerceptionComponent->OnPerceptionUpdated.AddDynamic(this, &AAIControllerUnit::SenseStuff);

I put this in the OnPosses function so that I know i’m dealing with a pawn or character of some kind but its not necessary (I needed it because the attack range was stored inside of my unit) Here we do some more setup for the sight sense and also make sure we can check for everything.

sightConfig->SightRadius = possessedUnit->sightRange;
sightConfig->LoseSightRadius = (possessedUnit->sightRange + 20.0f);
sightConfig->PeripheralVisionAngleDegrees = 360.0f;
sightConfig->DetectionByAffiliation.bDetectEnemies = true;
sightConfig->DetectionByAffiliation.bDetectNeutrals = true;
sightConfig->DetectionByAffiliation.bDetectFriendlies = true;

Do some stuff in the function that we registered earlier. testActors is an array of actors that have been detected by the Perception System (see below on how to add actors that can be found)

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

Finally add this line to any actors that you want to detect where sightConfig->GetSenseImplementation() is the sense you are registering for. (ie. if you want hearing you need to add the appropriate sense) In mine I put this in the controller of one of my AI though you could put it directly in the actor itself if you wanted.

UAIPerceptionSystem::RegisterPerceptionStimuliSource(this, sightConfig->GetSenseImplementation(), GetControlledPawn());

And that’s it, your done! If you AI can see anything registered it should fire the event and you can do stuff accordingly. Let me know if this was helpful or if you have any questions!

Edit: So idk if this will affect everyone but if your having a lot of crashes check this post out:



Alright, quick question…

I have a controller which can perceive an enemy (via sight using a 90 degree cone). When that happens, the OnPerceptionUpdate event gets fired and I set the percieved actor as the enemy.

When that enemy moves out of that pawns sensory range, there is no corresponding event which fires so I can’t run something which removes the actor from that controllers enemy list. How do you know when an object leaves your cone of perception?

Hey Slayemin, The OnPerceptionUpdate also fires when the actor leaves the cone of vision. You need to call another function to get the stimulus info for the actor to see if they’ve entered or exited. I think it’s called GetActorStimulus or something similar.

Hey, it appears that in 4.8 (PerceptionComponent->OnPerceptionUpdated.AddDynamic) is no longer a function. There is only .Add or .AddUnique. Either way both of these require a delegate to be passed in. My question is how to I declare/create this delegate
In my code I have (void SenseUpdated(TArray<AActor*> testActors):wink: but neither of those functions will accept that. How would I turn that into a delegate I can use.

Here’s mine:

if (GetPerceptionComponent())
		GetPerceptionComponent()->OnPerceptionUpdated.AddDynamic(this, &AGBAIController::PerceptionSenseUpdate);

Seems like AddDynamic works just fine. Maybe you need use GetPerceptionComponent?

AddDynamic is a macro, not a function. It’s kind of ugly, but just do as zoombapup shows and ignore any intellisense errors, it should work fine.

This hasn’t changed with 4.8 as far as I’m aware.

Thanks! I appreciate the help. Over relying on intellisense I suppose haha

Have anyone tried to set up hearing in C++? I’ve set up sight and I want to have hearing sense set up alongside sight, but somehow I can’t make it to sense any actors. Sight works fine but hearing is not sensing anything. Any clues what I might be doing wrong?

Edit2: see this for more info on what I’m currently doing and it’s not working: How to set up AI Perception hearing sense? - UE4 AnswerHub

You need to make sure that the thing making the noise is registered to take part in that sense, there’s a blueprint node for doing that which I forget the name of. RegisterPerceptionStimuliSource? Anyway, it basically registers with the sensory system as a provider of that sense. I think there’s an option in the sense config to automatically register objects with that sense, which maybe is why sight works?

Sure I read some documentation about it somewhere.

Yeah, I think I already did that:

In DefaultGame.ini, I’ve set:

And I even do it manually also on each actor OnBegin:
UAIPerceptionSystem::RegisterPerceptionStimuliSource(this, UAISense_Hearing::StaticClass(), this);

Is that what you mean?

Edit: Solved it. Look here for more details: How to set up AI Perception hearing sense? - UE4 AnswerHub

Thank you very much for the tutorial! I have only one question - what is the RegisterPerceptionStimuliSource method used for? I tried the code without it and it works just fine.

Hey there! I went to the link you published, because I’m getiing a lot of crashed.No idea why. But it shows a page not found. Can you repost the link? My AIPerception isn’t working at all :s