NPC 정찰 구현
NPC 정찰을 위한 행동트리 No Target 데코레이터는 추후 작성 예정
Sequence 컴포짓으로 대기, 정찰위치 지정, Move To 태스크 순서로 실행
Nav Mesh 생성 및 디버깅 방법
정찰 위치를 지정하기 위해 Nav Mesh가 필요
Place Actors → Volumes 에서 Nav Mesh Bounds Volume을 생성 후 NPC가 움직일 땅을 Nav Mesh 로 (영역안으로)지정
키보드 'P'를 누르면 Nev Mesh에 지정된 영역을 확인할 수 있음
플레이 버튼을 눌러 실행한 뒤 키보드 '를 누르면 AI 컨트롤러를 가지고 있는 액터를 디버깅할 수 있음
추후 구현할 Perception 및 행동트리, 네브 매쉬등 어떻게 동작하고 있는지 확인할 수 있음
BTTask_FindPatrolPos 생성
BTTaskNode를 상속받아 BTTask_FindPatrolPos을 생성
BTTaskNode_BlackboardBase는 BTTaskNode를 상속받아 BlackboardKey관련 함수 및 변수들이 추가 구현되어있음
BTTask_FindPatrolPos 헤더파일
#include "CoreMinimal.h"
#include "BehaviorTree/BTTaskNode.h"
#include "BTTask_FindPatrolPos.generated.h"
/**
*
*/
UCLASS()
class PROJECT_P_API UBTTask_FindPatrolPos : public UBTTaskNode
{
GENERATED_BODY()
public:
UBTTask_FindPatrolPos();
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
};
- UBTTask_FindPatrolPos();
- 생성자
- virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
- TaskNode가 실행될때 호출되는 ExecuteTask를 상속받음
Cpp 파일
생성자
UBTTask_FindPatrolPos::UBTTask_FindPatrolPos()
{
NodeName = TEXT("FInd Patrol Position");
}
생성자에서 행동트리에서 표시되는 노드이름을 지정
ExecuteTask
EBTNodeResult::Type UBTTask_FindPatrolPos::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
EBTNodeResult::Type Result = Super::ExecuteTask(OwnerComp, NodeMemory);
//#include "AIController.h" 추가
//BTTask의 OwnerComp(BT)에서 GetAIOwner로 BT를 소유하고있는 AI컨트롤러를 가져와 AI컨트롤러를 소유하고있는 폰을 가져옴
APawn* ControlPawn = OwnerComp.GetAIOwner()->GetPawn();
if (!IsValid(ControlPawn))
{
return EBTNodeResult::Failed;
}
//#include "NavigationSystem.h" 추가
//ControlPawn을 이용해 월드를 가져와 월드에서 UNavigationSystemV1을 가져옴
UNavigationSystemV1* NavSystem = UNavigationSystemV1::GetNavigationSystem(ControlPawn->GetWorld());
if (!IsValid(NavSystem))
{
return EBTNodeResult::Failed;
}
//블랙보드에 있는 데이터 가져오기
//#include "BehaviorTree/BlackboardComponent.h" 추가
FVector OriginPos = OwnerComp.GetBlackboardComponent()->GetValueAsVector(BBKEY_HOMEPOS);
FNavLocation NextPatrolPos;
float NextPosRadius;
//#include "AbilitySystemComponent.h", #include "Attribute/PPGruntAttributeSet.h"
//#include "AbilitySystemBlueprintLibrary.h" 추가
UAbilitySystemComponent* ASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(ControlPawn);
if (!IsValid(ASC))
{
return EBTNodeResult::Failed;
}
const UPPGruntAttributeSet* AttributeSet = ASC->GetSet<UPPGruntAttributeSet>();
if (!IsValid(AttributeSet))
{
return EBTNodeResult::Failed;
}
NextPosRadius = AttributeSet->GetAIPatrolRadius();
//GetRandomPointInNavigableRadius(기준 위치, 반지름(반경), 위치를 받아올 FNavLocation)
if (NavSystem->GetRandomPointInNavigableRadius(OriginPos, NextPosRadius, NextPatrolPos))
{
OwnerComp.GetBlackboardComponent()->SetValueAsVector(BBKEY_PATROLPOS, NextPatrolPos.Location);
return EBTNodeResult::Succeeded;
}
return EBTNodeResult::Failed;
}
ExeucteTask 함수는 Task의 실행결과를 반환함
- EBTNodeResult::Type Result = Super::ExecuteTask(OwnerComp, NodeMemory);
- 노드결과를 저장하는 Result변수를 생성
- 부모함수를 실행하여 결과 저장
- APawn* ControlPawn = OwnerComp.GetAIOwner()->GetPawn();
if (!IsValid(ControlPawn))
{
return EBTNodeResult::Failed;
}- ExecuteTask의 매개변수로 들어오는 OwnerComp를 이용하여 Pawn을 가져옴
- 만약 가져오지 못했다면 실패를 리턴
- #include "AIController.h" 추가
- UNavigationSystemV1* NavSystem = UNavigationSystemV1::GetNavigationSystem(ControlPawn->GetWorld());
if (!IsValid(NavSystem))
{
return EBTNodeResult::Failed;
}- #include "NavigationSystem.h" 추가
- UNavigationSystemV1의 스태이틱 함수 GetNavigationSystem를 사용하여 NavSystem을 가져옴
- ControlPawn을 이용해 월드를 가져와 월드에서 UNavigationSystemV1을 가져옴
- 만약 가져오지 못했다면 실패를 리턴
- FVector OriginPos = OwnerComp.GetBlackboardComponent()->GetValueAsVector(BBKEY_HOMEPOS);
- 블랙보드에 저장되어 있는 BBKEY_HOMEPOS를 가져와 저장
- FNavLocation NextPatrolPos;
- 네브매쉬를 이용해 다음 이동 장소를 저장할 변수
- float NextPosRadius;
- 네브매쉬의 반경을 저장할 변수
- UAbilitySystemComponent* ASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(ControlPawn);
if (!IsValid(ASC))
{
return EBTNodeResult::Failed;
}- #include "AbilitySystemComponent.h", #include "Attribute/PPGruntAttributeSet.h"
#include "AbilitySystemBlueprintLibrary.h" 추가 - ASC를 가져옴 못가져오면 실패 리턴
- #include "AbilitySystemComponent.h", #include "Attribute/PPGruntAttributeSet.h"
- const UPPGruntAttributeSet* AttributeSet = ASC->GetSet<UPPGruntAttributeSet>();
if (!IsValid(AttributeSet))
{
return EBTNodeResult::Failed;
}- NPC의 어트리뷰트셋을 가져옴 못가져오면 실패 리턴
- NextPosRadius = AttributeSet->GetAIPatrolRadius();
- 어트리뷰트에 저장된 정찰 반경을 가져옴
- NavSystem->GetRandomPointInNavigableRadius(OriginPos, NextPosRadius, NextPatrolPos)
- GetRandomPointInNavigableRadius(기준 위치, 반지름(반경), 위치를 저장할 FNavLocation)
- NavSystem을 이용하여 정찰위치를 가져옴
- 가져온게 성공하면
- OwnerComp.GetBlackboardComponent()->SetValueAsVector(BBKEY_PATROLPOS, NextPatrolPos.Location);
- 블랙보드에 정찰위치를 저장
- 태스크 결과 성공을 리턴
- return EBTNodeResult::Failed;
'포트폴리오 제작 > Project_P' 카테고리의 다른 글
Project_P 행동트리 모델 데코레이터 및 테스크 생성 (0) | 2024.12.10 |
---|---|
Project_P 행동트리 모델 AI Perception (0) | 2024.12.09 |
Project_P 행동트리 모델 생성 (1) | 2024.11.14 |
Project_P 체력바 UI 생성 (0) | 2024.10.21 |
Project_P GE를 사용하여 데미지 전달 및 체력 감소 (0) | 2024.10.18 |