게임개발/Unreal C++

[Unreal]#17_Behavior Tree

Hardii2 2022. 10. 4. 01:14

 

[Unreal]#17_Behavior Tree

Unreal 개발 중 "AI Controller"에 대해 알아보겠습니다.

"Simple Shooter Game"의 AI Player 개발 내용입니다.

 

 


 

Sequence

1. 화면

2. 기능

  • 컴포짓 노드(합성 노드)입니다.
  • 왼쪽에서 오른쪽으로 하위 노드들을 실행하고, 어느 하나가 실패할 때까지 실행합니다!
  • 하위 노드들 중 어느 하나가 실패하면, 이후에 다른 하위 노드들의 실행도 중지됩니다.
  • 모든 하위 노드들의 성공이 시퀀스의 성공입니다.
  • "가혹한" 노드라고 표현하겠습니다.
Selector

1. 화면

2. 기능

  • Selector 또한 컴포짓 노드입니다.
  • Sequence와 동일하게 왼쪽에서 오른쪽으로 하위 노드들을 실행합니다.
  • 하위 노드들 중 어느 하나가 성공할 때까지 수행합니다!
  • 하위 노드들 중 어느 하나가 성공하면, 이후에 다른 노드들은 실행이 중지됩니다.
  • 하나의 하위 노드의 성공이 Selector의 성공입니다!
  • "관대한" 노드로 표현하겠습니다.

 

Decorator

1. 화면

2. 기능

  • 각 노드에 추가할 수 있는, 말 그대로 데코레이터 노드입니다.
  • 데코레이터는 서포팅 노드로써, 부모-자식 관계에 위치하여 Work Flow에 대한 알림을 받습니다.
  • 미리 추가한 Blackboard 데코레이터 노드는 Blackboard의 특정 키의 상태에 따라서 성공 or 실패 여부를 체크.

 

Custom Task

1. BTTask C++클래스 생성

 

2. BTTask_ClearBlackboardValue.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "BehaviorTree/Tasks/BTTask_BlackboardBase.h"
#include "BTTask_ClearBlackboardValue.generated.h"

/**
 * 
 */
UCLASS()
class SIMPLESHOOTERNEW_API UBTTask_ClearBlackboardValue : public UBTTask_BlackboardBase
{
	GENERATED_BODY()
public:
	// 1. 생성자
	UBTTask_ClearBlackboardValue();
	// 2. ExecuteTask 가상 메서드
	virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
};
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory);
  • BTTask_ClearBlackboardValue 클래스가 상속하고 있는 "UBTTaskNode"클래스 제공 가상 메서드입니다.
  • 해당 노드를 실행하기위한 함수로 보이죠?

 

2. BTTask_ClearBlackboardValue.cpp

UBTTask_ClearBlackboardValue::UBTTask_ClearBlackboardValue()
{
	// 노드 이름 설정합니다
    NodeName = "Clear Value";
}

EBTNodeResult::Type UBTTask_ClearBlackboardValue::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
    Super::ExecuteTask(OwnerComp, NodeMemory);

    // 1. Blackboard Key 가져오기
    FName KeyName = GetSelectedBlackboardKey();
    // 2. Key 값 Clear 하기
    OwnerComp.GetBlackboardComponent()->ClearValue(GetSelectedBlackboardKey());

	// 3. EBTNodeResult 열겨형을 리턴합니다.
    return EBTNodeResult::Succeeded;
}
UENUM(BlueprintType)
namespace EBTNodeResult
{
	// keep in sync with DescribeNodeResult()
	enum Type
	{
		Succeeded,		// finished as success
		Failed,			// finished as failure
		Aborted,		// finished aborting = failure
		InProgress,		// not finished yet
	};
}
  • 주의할 점은 "Super"를 통해 부모의 것을 호출해야 합니다!
  • 더불어, EBTNodeResult 열거형을 반환해야 합니다!

 

4. SimpleShooterNew.Build.cs

  • Build.cs 파일 내부 PublicDependencyModuleNames에 "GameplayTasks"를 추가해줍니다.

 

5. Custom BTTask Node 추가

 

Behavior Tree 예제

1. 화면

 

2. 설명

  1. Selector : 어느 하나 성공할 때까지 "왼쪽 하위 노드 -> 오른쪽 하위 노드" 이동
  2. Chase + Can See Player : 시야에 존재하는 Player의 위치를 저장하고 해당 위치로 이동
  3. Investigate + Can Find Player : 시야에 존재하지 않는 Player의 마지막 위치로 이동 혹은 탐색
  4. Move To : 앞선 하위 노드들이 모두 실패하면 5초 대기하고, 다시 시작 위치로 이동합니다.
  5. *Observe Blackboard Value : 블랙보드 키 값을 지속적으로 관찰할것인지 여부를 확인합니다.

 

3. 결과 화면