플레이어를 상대하는 인공지능 적 AI를 생성해보겠습니다
언리얼에서 AI는 크게 Behavior Tree방식과 FSM 방식 두가지가 있습니다
저는 이번에는 Behavior Tree방식의 AI를 구성해보도록하겠습니다
Behavior Tree와 Black Board를 생성해줍니다
Behavior Tree | AI가 어떤 행동을 할지 결정하는 두뇌역할을 하는 Tree(구조체) |
Black Board | AI가 사용하는 데이터의 집합체 |
Behavior Tree는 총 5가지의 노드가 존재합니다
루트(Root) | Behavior Tree의 시작을 나타내는 노드입니다 |
컴포짓(Composite) | 셀렉터, 시퀀스, 심플 페러렐 로 이루어져있는 분기가 실행되는 규칙을 정의하는 노드입니다. |
태스크(Task) | 실제 행동을 수행하는 노드입니다. |
데코레이터(Decorator) | 블랙보드값에 의거하여 컴포짓노드를 실행할지에 대한 여부를 결정하는 노드입니다. |
서비스(Service) | 주기적으로 계속 실행되는 조건 체크를 해주는 노드입니다. |
C++작업을 하기 앞서 Build.Cs 파일을 수정해주겠습니다
AIModule를 추가해주겠습니다
(Build.cs파일을 수정한뒤에는 꼭 프로젝트를 한번 generate 해주는걸 권장합니다)
Tree를 작동시킬 플레이어 컨트롤러 또한 만들어주겠습니다
AIController를 종속받는 AI컨트롤러 C++를 생성해주겠습니다
BlackBoard(BB)와 BehaviorTree(BT)를 들고오겠습니다
cpp에 필요한 헤더를 추가시킵니다
#include "BehaviorTree/BehaviorTree.h"
#include "BehaviorTree/BlackboardData.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "BehaviorTree//BehaviorTreeComponent.h"
cpp코드를 작성합니다
ASkeletonAIController::ASkeletonAIController()
{
//BT
static ConstructorHelpers::FObjectFinder<UBehaviorTree> bt(TEXT("/Game/Luco/Enemy/BT_Skeleton.BT_Skeleton"));
if (bt.Succeeded())
{
btAsset = bt.Object;
}
//BB
static ConstructorHelpers::FObjectFinder<UBlackboardData> bb(TEXT("/Game/Luco/Enemy/BB_Skeleton.BB_Skeleton"));
if (bb.Succeeded())
{
bbAsset = bb.Object;
}
}
void ASkeletonAIController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
RunAI();
}
void ASkeletonAIController::RunAI()
{
if (UseBlackboard(bbAsset, bbComp))
{
RunBehaviorTree(btAsset);
}
}
void ASkeletonAIController::StopAI()
{
UBehaviorTreeComponent* behaviorTreeComponent = Cast<UBehaviorTreeComponent>(BrainComponent);
if (nullptr == behaviorTreeComponent) return;
behaviorTreeComponent->StopTree(EBTStopMode::Safe);
}
AIController 내에서 BT를 Possess하는 코드입니다
사용할 적 AI에게 AIController를 할당시킵니다
여기까지했다면 AI는 현재 BT를 작동하게됩니다
그럼 이제 AI가 플레이어를 감지하도록 하게 해보겠습니다
제가 채용한 시야방식은 AIPerception 방식입니다.
AIPerception 사용을 위한 헤더를 추가합니다
#include "Perception/AIPerceptionComponent.h"
#include "Perception/AISenseConfig_Sight.h"
생성자에서 AIPerceptionComponent와 SenseConfig를 생성해줍니다
perception = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("AIPerceptionComponent"));
sight = CreateDefaultSubobject<UAISenseConfig_Sight>("Sight Config");
sight->SightRadius = 600; //sense distance
sight->LoseSightRadius = 800; //lostsense distance
sight->PeripheralVisionAngleDegrees = 45; //sense degree
//sense enemy
sight->DetectionByAffiliation.bDetectEnemies = true;
//no sense neutrality
sight->DetectionByAffiliation.bDetectNeutrals = true;
//sense friend
sight->DetectionByAffiliation.bDetectFriendlies = false;
perception->SetDominantSense(*sight->GetSenseImplementation());
perception->ConfigureSense(*sight);
//perception update
perception->OnPerceptionUpdated.AddDynamic(this, &ASkeletonAIController::OnPerceptionUpdated);
RunAI 함수를 없애고 OnPossess함수에서 BT가 실행되도록 바꿔주었습니다
void ASkeletonAIController::BeginPlay()
{
Super::BeginPlay();
}
void ASkeletonAIController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
if (UseBlackboard(bbAsset, bbComp))
{
RunBehaviorTree(btAsset);
}
}
void ASkeletonAIController::OnPerceptionUpdated(const TArray<AActor*>& DetectPawn)
{
TArray<AActor*> actors;
perception->GetCurrentlyPerceivedActors(nullptr, actors);
//if sensing over 1
if (actors.Num() > 0)
{
UE_LOG(LogTemp, Warning, TEXT("%s"), *actors[0]->GetName());
return;
}
}
void ASkeletonAIController::StopAI()
{
UBehaviorTreeComponent* behaviorTreeComponent = Cast<UBehaviorTreeComponent>(BrainComponent);
if (nullptr == behaviorTreeComponent) return;
behaviorTreeComponent->StopTree(EBTStopMode::Safe);
}
그럼 적AI Controller에 aiperception이 달렸습니다
aiperception에 감지가 되면 감지가 된 액터의 이름을 출력하도록 세팅했습니다
확인해보겠습니다
프로젝트세팅 -> 게임플레이 디버거 -> Active In Game -> 인덱스4번에 있는 Perception Game:On을 Enable 로변경
디버거모드를 키는방법은 엔터옆의 ' 키를 누르시면됩니다
Perception이 잘 달리고 세팅한 시야각 45도 만큼 잘 작동하는걸확인할수있습니다
'Unreal5 프로젝트 다이어리' 카테고리의 다른 글
Unreal - Behavior Tree(3) 플레이어와의 상호작용 (0) | 2025.05.02 |
---|---|
Unreal - Behavior Tree(2) 플레이어 따라가기 (0) | 2025.04.29 |
Unreal - 8방향 블렌드스페이스(BlendSpace) (0) | 2025.04.27 |
Unreal - 미니맵 만들기 (0) | 2025.04.25 |
Unreal - 마우스 커서 바꾸기 (0) | 2025.04.25 |