참고 문서
책 '이득우의 언리얼 C++ 게임 개발의 정석' Chapter 12
&
태스크 노드란?
언리얼 문서에 이렇게 설명되어있다.
These are the leaves of the Behavior Tree,
these nodes are the actionable things to do and don't have an output connection.
// 번역해보면,
비헤이비어 트리의 마지막 노드로,
이러한 노드는 실행 가능한 것들이고, 출력 연결이 없습니다.
태스크 노드 만들기
BTTaskNode를 부모 클래스로 하는 클래스를 생성한다.
클래스명은 BTTask_FindPatrolPos로 했다.
이 클래스에는 랜덤한 위치를 지정하는 기능을 만들 것이다.
언리얼에서 노드 이름을 표시할 때, BTTask_ 부분은 자동으로 걸러진다.
(BTTask Find Patrol Pos 1)이라고 뜨는 것은 언리얼을 껏다 키면 사라진다. 일종의 버그인 것 같다.
Task와 관련된 모듈을 참조할 수 있도록, Build 파일에 "GameplayTasks" 모듈을 추가한다.
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG", "AIModule", "GameplayTasks" });
Task 내에서 Navigation 기능을 사용할 것이라서, "NavigationSystem" 모듈도 추가해준다.
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG", "AIModule", "GameplayTasks", "NavigationSystem" });
태스크 노드 클래스
ExecuteTask() 함수를 오버라이딩해서 구현한다.
ExecuteTask() 함수는 Aborted, Failed, Succeeded, InProgress의 반환 값을 가진다.
Aborted : 태스크 실행 중에 중단. 결과적으로 실패.
Failed : 실패.
Succeeded : 성공.
InProgress : 나중에 결과 알려줄 예정.
UCLASS()
class ARENABATTLE_API UBTTask_FindPatrolPos : public UBTTaskNode
{
GENERATED_BODY()
public:
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
};
태스크 노드 내용 구현하기
GetRandomPointInNavigableRadius() 함수로 랜덤한 위치를 얻어서, Blackboard의 키 값에 저장하는 기능이다.
#pragma once
#include "CoreMinimal.h"
#include "BehaviorTree/BTTaskNode.h"
#include "BTTask_FindPatrolPos.generated.h"
UCLASS()
class ARENABATTLE_API UBTTask_FindPatrolPos : public UBTTaskNode
{
GENERATED_BODY()
public:
UBTTask_FindPatrolPos();
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
};
#include "BTTask_FindPatrolPos.h"
#include "ABAIController.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "NavigationSystem.h"
UBTTask_FindPatrolPos::UBTTask_FindPatrolPos()
{
NodeName = TEXT("FindPatrolPos");
}
EBTNodeResult::Type UBTTask_FindPatrolPos::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
APawn* ControllingPawn = OwnerComp.GetAIOwner()->GetPawn();
if (nullptr == ControllingPawn) return EBTNodeResult::Failed;
UNavigationSystemV1* NavSystem = UNavigationSystemV1::GetNavigationSystem(ControllingPawn->GetWorld());
if (nullptr == NavSystem) return EBTNodeResult::Failed;
FVector Origin = OwnerComp.GetBlackboardComponent()->GetValueAsVector(AABAIController::Key_HomePos);
FNavLocation NextPatrol;
if (NavSystem->GetRandomPointInNavigableRadius(FVector::ZeroVector, 500.0f, NextPatrol))
{
OwnerComp.GetBlackboardComponent()->SetValueAsVector(AABAIController::Key_PatrolPos, NextPatrol.Location);
return EBTNodeResult::Succeeded;
}
return EBTNodeResult::Failed;
}
비헤이비어 트리에 Blackboard가 연결되어있어야 노드에서 Blackboard 키에 접근이 가능하다.
실행 결과
움짤이 이상하면, 클릭해서 보면 제대로 보입니다. (크기 1.07MB)
'기타 > Unreal' 카테고리의 다른 글
[Unreal Error] 앱 실행 도중 pure virtual 함수가 호출되고 있었습니다 (GIsRunning == 1). (6) | 2021.05.12 |
---|---|
[Unreal C++] Behavior Tree 4 (서비스 사용하기) (0) | 2021.05.11 |
[Unreal C++] Behavior Tree 2 (블랙보드 값 이용하기) (0) | 2021.05.11 |
[Unreal C++] Behavior Tree 1 (비헤이비어 트리 실행하기) (5) | 2021.05.11 |
[Unreal Error] UWidgetComponent::GetUserWidgetObject()가 Null 값을 반환하는 경우 (5) | 2021.05.11 |