AIController
is the base class of controllers for AI-controlled Pawns.
While the PlayerController relies on the human player to make decisions on what to do, the AIController is more focused on responding to input from the environment and game world. The job of the AIController is to observe the world around it and make decisions and react accordingly without explicit input from a human player.
Inheritance Hierarchy
- UObjectBase
- UObjectBaseUtility
- UObject
- AActor
- AController
- AActor
- UObject
- UObjectBaseUtility
It may be handy to use the AIController
with Artificial Inteligence
→ Behavior Tree
and Blackboard
tools.
// .h file
class UBehaviorTree* AIBehavior;
// .cpp file
#include "BehaviorTree/BlackboardComponent.h"
void AExampleAIController::BeginPlay()
{
Super::BeginPlay();
if(AIBehavior != nullptr) RunBehaviorTree(AIBehavior);
}
void AExampleAIController::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
// All the code below can be moved to BTT serice - see the BTTService example below
APawn *PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
if(LineOfSightTo(PlayerPawn)){
GetBlackboardComponent()->SetValueAsVector(TEXT("PlayerLocation"), PlayerPawn->GetActorLocation());
} else {
GetBlackboardComponent()->ClearValue(TEXT("PlayerLocation"));
}
}
BTT services
With using a Behavior Tree
, there's possible to create own custom C++ UBTService
s (New C++ Class
→ BTService_BlackboardBase (through show all classes)
). Then, we can place it in necessary places in the Behavior Tree logic and avoid of processing certain task (updating a value in this case) only when it's necessary for the right function logic.
// .h file
UCLASS()
class ExampleApp_API UBTService_PlayerLocationIfSeen : public UBTService_BlackboardBase
{
GENERATED_BODY()
public:
UBTService_PlayerLocation();
protected:
virtual void TickNode(UBehaviorTreeComponent &OwnerComp, uint8 *NodeMemory, float DeltaSeconds) override;
}
// .cpp file
#include "BehaviorTree/BlackboardComponent.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/Pawn.h"
#include "AIController.h"
UBTService_PlayerLocationIfSeen::UBTService_PlayerLocationIfSeen()
{
NodeName = "Update Player Location If Seen";
}
void UBTService_PlayerLocationIfSeen::TickNode(UBehaviorTreeComponent &OwnerComp, uint8 *NodeMemory, float DeltaSeconds)
{
Super::TickNode(OwnerComp, NodeMemory, DeltaSeconds);
APawn *PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
if(PlayerPawn == nullptr) return;
if(OwnerComp.GetAIOwner() == nullptr) return;
if(OwnerComp.GetAIOwner() ->LineOfSightTo(PlayerPawn))
{
// For Vectors
OwnerComp.GetBlackboardComponent()->SetValueAsVector(GetSelectedBlackboardKey(), PlayerPawn->GetActorLocation());
// For Objects
OwnerComp.GetBlackboardComponent()->SetValueAsObject(GetSelectedBlackboardKey(), PlayerPawn);
} else {
OwnerComp.GetBlackboardComponent()->ClearValue(GetSelectedBlackboardKey());
}
}