When?
인공지능의 행동 양식을 구현할 때 사용한다.
Why?
간단한 행동양식인 경우에는 각 FSM과 같이 State를 이동하며, 행동양식을 만들 수 있다.
하지만 복잡한 행동양식인 경우에 State가 많아질수록 기하급수적으로 복잡해진다는 단점이 있다.
이를 해결하기 위해, Tree형태로 행동양식을 결정하는 Behavior Tree가 등장했고, 유지보수에 강한 장점이 있다.
How?
AIController 내부에는 BrainComponent와 BlackBoardComponent가 준비되어 있다.
BrainComponent는 BehaviorTree의 부모로, RunBehaviroTree() 에서 BTComp와 BBComp가 NewObject를 통해 만들어진다.
두 Component의 내부에는 당연히도 BT와 BB가 있는데, BT는 내부에 BB를 멤버로 가지고 있기에, RunBehaviorTree에서 BT Asset만을 인자로 받는다.
BlackBoard
BlackBoard는 Behavior Tree에서 사용할 Key값의 모음이라고 생각하면 된다.
각 Key값의 Value로 어떤 Class를 할당할 지, 설정할 수 있다.
BlackBoard Asset을 Parent로 삼아 Child BlackBoard를 만들 수 있다.
Class의 Static 멤버 처럼 어떤 Key값을 같은 BlackBoard Instance에서 공유할 수 있다.
Behavior Tree
BehaviorTree의 구성요소는 크게 Composite, Task, Decorator, Service Node로 나뉜다.
Composite와 Task는 성공과 실패의 개념이 있으며, 이는 Behavior Tree의 중요한 작동 원리이다.
Decorator는 어떤 노드가 실행되기 전, 조건을 판별한다.
Service는 주기적, 혹은 노드의 상태에 따라 논리를 실행한다.
Composite Node
- Selector : 자식 노드들을 돌며, 실행 가능한 노드를 찾는다. 하나라도 성공하면 성공.
- Sequence : 자식 노드들을 우선순위대로 실행한다. 실행과정중 하나라도 실패하면 실패.
- Simple Parallel : MainTask와 SubTask를 동시에 실행한다. MainTask가 종료되면 SubTask도 종료된다. ( Option으로 SubTask의 종료를 기다릴 수 도 있다.)
Task Node
Behavior에 해당하는 부분으로, 행동 논리를 가진다.
bNotifyTick을 통해 TickTask을 사용할 수 있다.
Task가 실행될 때, ExecuteTask가 호출되며, EBTNodeResult::Type의 반환값을 가진다.
여기서 만약 EBTNodeResult::Progress를 반환하면, TickTask나 어딘가에서 FinishLatentTask를 통해 Task가 종료되었음을 알려주어야 한다.
Decorator
데코레이터는 Observer Aborts라는 Option을 가진다.
이는 Decorator가 관찰하고 있는 값이 어떤 조건을 만족한다면, 자신을 Root로 하는 SubTree나, 자신보다 우선순위가 낮은 SubTree의 Task를 강제로 끝낼 수 있다.
이로 인해, Root부터 다시 분기를 평가 받을 수 있다.
Service
Service를 포함한 Node가 활성화 되거나, 비활성화 될 때, 활성화 되어 있는 동안, 어떤 로직을 한 번만, 혹은 주기적으로 실행할 수 있다.