관리 메뉴

기억을 위한 기록들

[UE4] Behavior Tree에 관하여(1)- Composites(Sequence/Selector/Simple Parallel) 본문

UnrealEngine/UE- BehaviorTree

[UE4] Behavior Tree에 관하여(1)- Composites(Sequence/Selector/Simple Parallel)

에드윈H 2022. 3. 27. 15:25

보통 글을 잘쓰는것보다 잘쓰여져 있는글을 가져오는게 낫다고 생각 할 때가 있다. 인터넷은 너무나도 많은 정보들을 담고 있 해당 비헤이비어 트리에 관련되서, 2014년도에 글을 작성해주신 분이 계신데 내가 엉성하게 쓰는것보다 해당 글을 가져오는게 낫다고 생각했다. 

 

컴포짓(Composites)이란?

- 컴포짓은 상태들의 시작점이다. 상태가 복귀와 실행 플로우에서 어떻게 행동해야하는지 정의한다.

여기에는 Selector/Sequence/Simple Parallel 이렇게 세가지 종류가 있다.

 

비헤이비어 트리안에 오른쪽 마우스 클릭시 보이는 컴포짓들

1. Background
 
BT는 AI 캐릭터를 만들기 위한 매우 유명한 도구 중 하나입니다. Halo2[Bungie Software, 2004]가 BT를 사용한 최초의 게임으로 알려져 있고, 그 후 많은 게임에서 BT를 적극적으로 활용하기 시작했습니다.
  BT에는 계층적 FSM, 스케쥴링, Planning, Action Execution 등의 개념이 결합되어 있습니다. 특히 계층적 FSM과 상당히 많은 유사점이 존재하는데, FSM의 경우 가장 중요한 요소가 상태(State)인 반면, BT의 메인 요소는 'Task'입니다. Task는 보다 복잡한 액션을 표현하는 서브트리로 구성이 됩니다. 다시 말해 이러한 복잡한 액션들이 모여 보다 고수준의 행위를 구성한다고 보면 될 것 같습니다.. 이러한 점이 BT가 손쉽게 다양한 행위를 표현하는 가장 큰 능력입니다. 모든 Task들은 공통의 인터페이스를 가지고 있고, 그 자체가 독립적으로 모듈화되어 있어 계층적 구조를 쉽게 구성할 수 있습니다.
 
2. Task의 Type
 
BT에서 Task들은 동일한 기본 구조를 가집니다. 하나의 task가 가동되고 난 후 그 결과는 성공과 실패의 형태(불린)로 출력됩니다. Task에는 크게 다음의 3가지 종류로 나눌 수 있습니다.
 
- Condition
- Action
- Composite

 
Condition : 말 그대로 조건에 대한 검사를 의미합니다. 예를 들어 적이 X unit 반경 내에 존재 유무, LOS(Line of Sight) 검사, 캐릭터의 상태(건강치, 무기 보유여부 등) 등 현재 캐릭터가 원하는 질의(query)를 표현할 수 있습니다.
 
Action : 게임의 상태를 변경시킵니다. 애니메이션에 대한 액션 변경, 캐릭터의 움직임, 캐릭터의 내부 상태의 변경(건강치가 올라간다거나 하는 등), Audio 샘플의 플레이, 특정한 AI 코드의 실행 등 실제 캐릭터의 변화에 대한 수행을 의미합니다.
 
사실 위의 Condition이나 Action 등은 결정트리(Decision Tree)나 FSM 에서 사용하는 기법과 매우 유사합니다. 가장 핵심적인 차이는 BT에서는 유일한 공통 인터페이스로 이 모든 task들이 사용된다는 점입니다.
 
Composite : Condition이나 Action은 BT에서 단말노드에 존재합니다. 그 외에 다른 비단말 노드는 Composite Task로 구성됩니다. 이름이 내포하듯 Composite는 Condition, Action 그리고 다른 Composite를 자식노드로 결합하는 역할을 합니다.
 
 
3. Composite Task의 Type
 
Composite Task에는 크게 Selector와 Sequence 두 종류가 있습니다(사실 세 종류입니다. Parallel Task인데 이는 나중에 따로 다루도록 하겠습니다). 이 둘 모두 그들의 자식 노드를 순차적으로 방문합니다. 하나의 자식 노드가 수행을 완료하면 그 결과값(True or False)을 반환하는데 Composite Task는 그 결과값을 보고, 진행을 계속할지 멈출지를 결정합니다.
 
Selector : Selector의 경우 자식노드가 성공하면 바로 그 결과를 반환합니다. 하나의 자식노드가 실패하면 그 다음 자식노드로 진입하는데 모든 자식노드가 실패할 경우를 제외하면 성공 시점에서 실행을 멈춥니다. 이를 달리 말하면 하나의 행위를 수행하는데 다양한 액션이 취사선택 가능할 경우 사용된다고 보면 될 것 같습니다.
 
Sequence : Sequence는 자식노드가 성공하면 계속 순차방문을 하고, 자식노드가 실패하는 경우 실행을 중지하는 구조로 이루어져 있습니다. 이는 일련의 액션 전부가 성공해야만 하나의 행위가 완성되는 것을 의미합니다.
[출처] Introduction to Behavior Tree (1) : Type of Task|작성자 DeepBlue

 

 

UE4에서의 Sequence와 Selector

Sequence 노드

간단하게 Sequence(시퀀스)는 왼쪽부터 오른쪽으로 아래 노드를 타고가 true인지를 확인하게 된다.

SequenceValue가 0이라서 왼쪽 노드에서 3초 뒤에 오른쪽 노드로 바뀐다
3초후 오른쪽 노드를 타고 다시 3초뒤 왼쪽으로 다시 순환된다.

왼쪽 블랙보드의 SequnceValue is Not Equal To 0.0 으로 바꾸면

 

 

애초에 왼쪽 노드에 진입하지도 않게 된다.

 

 

* 시퀀스 노드는 간단히 요약하자면 왼쪽노드부터 오른쪽으로 순차적으로 노드가 진행되고 되는중간 false가 발생하면 오른쪽 노드로 넘어가지 않는다.

* 시퀀스 노드는 하위 노드가 모두 성공해야 해당 시퀀스가 완료 된다.

 

 

 

Selector 노드

같은 조건에하에 Selector 노드로 확인해보자.

셀렉터 노드는 왼쪽부터 검사하는게 검사하기는 하나 왼쪽노드가 마무리 되더라도 오른쪽 노드로 넘어가지 않는다.

그리고 왼쪽에 있는 노드조건이 안맞더라도 오른쪽 노드로 넘어가게 된다.

 

즉 간단히 정리하자면 시퀀스(Sequence) 노드는 중간 조건이 실행되지 않는다면, 마치 while문 안에서 break로 while문을 탈출하게 되면서 그 아래에 있던 노드들이 동작하지 않는꼴이다.

 셀렉터(Selector)노드는 while 안에서 break가 나더라도 그 상황에 대비하여 다른 로직이 동작하게 되는것과 같은 것 같다.

 

셀렉터는 하위 노드들이 성공적으로 실행됐는지 확인하지 않은 상태에서 사용하는게 좋다.

해당 글에서 ?는 Selector 로  ->는 Sequence로 비유를 들어주셨다.

 

https://blog.naver.com/devdeepblue/220045888468

 

1. 첫번째 시퀀스에서는

2. 문이 열려 있는지?

3. 후에 열려있다면 room으로 들어가는 시퀀스이고,

4. 다음 시퀀스에서는

5. 문 근처로 다가가고

6. 문이 잠겨있는지 확인하기 위한 selector로

7. 문이 잠겨있을 경우의 시퀀스로 

8. 문이 잠겨 있다면

9. 문을 열고

10. 문이 그냥 열려 있는 시퀀스이고,

11. 문이 열려있는지 확인하고

12. 문을 여는 행동을 취한다

13. 그리고 문으로 들어가도록 정리를 해보았다.

 

이렇게 보니 해당 글쓴이는 트리의 순회가 마치 알고리즘에서 DPS(깊이 우선 탐색/Depth First Search)구조인걸 파악하였다.

 

 

 

https://blog.naver.com/devdeepblue/220045768366

 

Introduction to Behavior Tree (1) : Type of Task

1. Background BT는 AI 캐릭터를 만들기 위한 매우 유명한 도구 중 하나입니다. Halo2[Bungie Soft...

blog.naver.com