Unreal Engine AI Perception Component C++

·

·

The AI Perception Component can be setup within an AAIController to receive and react to additional sensory data like sight, vision and touch. This allows developers to program advanced AI behavior, for example, enemy AI raising the alert level based on the sounds of the player footstep. Used properly, the AI Perception Component can create a wow factor among the players as far the perceived smartness of the AI is concerned. The component can be particularly useful when designing and implementing stealth mechanics.Setting up the AAIController with the perception component and, subequently, handling the perception stimuli is quite straight forward.First, we setup our header file, we will call this ABasicAIController.

UCLASS()
class PAPERPLANES_API ABasicAIController : public AAIController
{
	GENERATED_BODY()

public:
	ABasicAIController();

protected:
	virtual void BeginPlay() override;
	virtual void OnPossess(APawn* InPawn) override;

public:
	UFUNCTION(BlueprintCallable, Category = "LostFerry", meta = (AllowPrivateAccess = true))
	void PerceptionUpdated(AActor* Actor, FAIStimulus Stimulus);
	
private:
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "LostFerry", meta = (AllowPrivateAccess = true))
	TObjectPtr<UBehaviorTree> BehaviorTree;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "LostFerry", meta = (AllowPrivateAccess = true))
	TObjectPtr<UBehaviorTreeComponent> BehaviorTreeComponent;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "LostFerry", meta = (AllowPrivateAccess = true))
	TObjectPtr<UBlackboardComponent> BlackboardComponent;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "LostFerry", meta = (AllowPrivateAccess = true))
	TObjectPtr<UAIPerceptionComponent> AIPerceptionComponent;
};
Code language: C++ (cpp)

Besides BehaviorTree, BehaviorTreeComponent and BlackboardComponent which we included for completeness, we are primarily concerned with AIPerceptionComponent which is an UObject of the type UAIPerceptionComponent.

Now for the implementation in the .cpp file.

ABasicAIController::ABasicAIController()
{
	BehaviorTreeComponent = CreateDefaultSubobject<UBehaviorTreeComponent>(
		TEXT("Behaviour Tree Component")
	);
	BlackboardComponent = CreateDefaultSubobject<UBlackboardComponent>(
		TEXT("Blackboard Component")
	);
	AIPerceptionComponent = CreateDefaultSubobject<UAIPerceptionComponent>(
		TEXT("AIPerception")
	);
}

void ABasicAIController::BeginPlay()
{
	Super::BeginPlay();

	if (IsValid(BehaviorTree.Get()))
	{
		RunBehaviorTree(BehaviorTree.Get());
		BehaviorTreeComponent->StartTree(*BehaviorTree.Get());
	}

	PerceptionComponent->OnTargetPerceptionUpdated.AddDynamic(this, &ABasicAIController::PerceptionUpdated);
}

void ABasicAIController::OnPossess(APawn* InPawn)
{
	Super::OnPossess(InPawn);

	if (IsValid(BlackboardComponent.Get()) && IsValid(BehaviorTree.Get()))
	{
		Blackboard->InitializeBlackboard(*BehaviorTree.Get()->BlackboardAsset.Get());
	}
}

void ABasicAIController::PerceptionUpdated(AActor* Actor, FAIStimulus Stimulus)
{
	if (if (Stimulus.WasSuccessfullySensed()))
	{
		if (Stimulus.Type == UAISense::GetSenseID<UAISense_Hearing>())
		{
			// Handle updates to the hearing sense
			// Example: calculate the distance between the stimulus receiver and the source
			const float Distance = FVector::Dist(Stimulus.ReceiverLocation, Stimulus.StimulusLocation);
		}
		else if (Stimulus.Type == UAISense::GetSenseID<UAISense_Sight>())
		{
			// Similarly, handle updates to the (eye) sight sense
		}
	}
}
Code language: C++ (cpp)

We initialize all the objects in the constructor and, in the function, OnPossess, we initialize our blackboard. Inside BeginPlay we attach the behavior tree to our AI controller and execute (start) it. Next we bind to the event OnTargetPerceptionUpdated which will call PerceptionUpdated and this is where we can implement the desired logic of handling the stimuli of interest.

OnTargetPerceptionUpdated event executes the callback function with an AActor* parameter pointing to the actor which triggered the perception stimuli and a FAIStimulus struct containing the data with respect to the triggered stimuli.


Leave a Reply

Your email address will not be published. Required fields are marked *