-
유니티 - 비헤이비어 트리 : BT(Behavior Tree) 개념잡기 와 예시TIL 2023. 10. 27. 17:43반응형
★짚고 넘어가야 하는 부분
◆ '노드' 란?
마디, 접속점, 교점, 접속점 등의 의미를 가진다.컴퓨터 과학에 쓰이는 기초적인 단위이다.
데이터를 포함하며 다른 노드와 연결될 수도 있다.
노드는 하나의 자료 구조에 포함된 정보를 표현한다.
-노드들은 값이나 조건을 포함 가능함
-다른 독립된 자료 구조의 역할을 할 가능성이 있음
-노드는 하나의 부모 노드에 의해 표현됨
루트 노드(root node): 트리 구조의 가장 높은 지점
- 이 노드에는 부모 노드가 없으나해당 트리 아래에 속한 모든 노드의 부모노드나 조부모 노드의 역할을 맡는다
.
노드의 높이는 해당 노드에서 가장 거리가 먼 리프 노드(leaf node)까지의
경로 상의 간선의 전체 수에 의해 결정되며
트리의 높이는 루트 노드의 높이와 동등하다.
노드의 깊이(depth)는 특정 노드와 루트 노드 간의 거리에 의해 결정된다.
루트 노드는 0의 깊이를 갖는다고 말할 수 있다.
쉽게 생각하자면, 어떠한 연결 및 호출에 대해 반응하는
실행 정보를 담은 박스를 생각하면 될 것 같다.
[간단한 예시로 자주 사용했던 Animator의 Walk, Run 등등의 박스들도 노드인 것이다.]
#1. BT의 소개와 FSM에 관한 짧은 내용( ★ 부분 보충 필요)
FSM의 단점 : 상태 추가시 점점 복잡하고 서로서로 꼬이게 됨
FSM에서는 상태 전이 조건을 모두 각각의 상태에서 검사함
하지만 BT에서는 상태 동작 뿐 아니라 전이 조건도 노드로 관리한다.
==>
BT는 노드 그래프를 통해 시각화하거나 params, 빌더 패턴 등을 활용하여
스크립트 내에서도 가독성 좋게 구성할 수 있다.
[★BT와 관련한 params, 빌더 패턴 추가적으로 찾아보기]빌더 패턴의 경우 강의를 메모해놓은 부분이 있었다.
https://qlxm0828.tistory.com/136
강의 - 디자인 패턴 - 빌더(빌드) 패턴
빌더 패턴 객체 생성 시 복잡한 과정이 있을 수 있다. 그러한 복잡한 생성 과정을 분리해서 다양한 구성의 인스턴스를 만드는 생성 패턴이다. 생성 패턴이란? 인스턴스를 만드는 절차를 추상화
qlxm0828.tistory.com
◆ params(가변 인자 매개변수) //이번에 찾아서 추가로 작성했다.
https://qlxm0828.tistory.com/137
기본적으로 Leaf, Decorator, Composite 노드를 기반으로 하며,
구현은 많이 다를 수 있다.
Leaf : 동작을 수행하는 노드, 대표적으로 Action 또는 Task 노드가 있다.
Decorator : 다른 노드에 조건을 붙여 수식하는 노드
Composite : 자식 노드들을 가지며, 자식들을 순회하거나 선택하는 역할을 수행하는 노드
#2. 노드 구성
*모든 노드는 실행의 결과로 true 또는 false를 반환한다.
*Decorator는 가독성을 위해 Composite와 Leaf들의 구성으로 대체한다.
1) 인터페이스
a. INode
최상위 노드 클래스
bool Run(); 메서드를 가진다.
b. ILeafNode : INode
트리와 각 말단을 이루는 주요 수행 노드
Action 또는 Condition 이 해당된다.
INode를 상속받는다.
c. IDecoratorNode : INode
다른 노드들을 수식하여 동작 조건을 지정하는 노드
마찬가지로 INode를 상속받는다.
d. ICompositeNode : INode
자식들을 순회하기 위한 노드
인터페이스 구현 시 List ChildList 멤버를 작성한다.
마찬가지로 INode를 상속받는다.
2) 클래스
a. ActionNode : ILeafNode
주요 동작을 수행하는 역할을 하며, 무조건 true를 리턴한다.
ILeafNode를 상속받는다.
b. ConditionNode : ILeafNode
조건식을 검사하며, 그 결과를 리턴한다.
ILeafNode를 상속받는다
c. SelectorNode : ICompositeNode
자식들 중 true인 노드를 만날 때까지 차례대로 순회한다.
자식이 false일 경우 계속해서 다음 자식 노드를 실행하고, true일 경우 순회를 중지한다.
모든 자식 노드가 false 일 경우 Selector 노드도 false를 리턴하고 종료하며,
true인 자식 노드를 만난 경우 마찬가지로 Selector 노드가 true를 리턴하고 종료하게 된다.
ICompositeNode를 상속받는다.
d. SequenceNode : ICompositeNode
자식들 중 false인 노드를 만날 때까지 차례대로 순회한다.
자식이 true일 경우 계속해서 다음 자식 노드를 실행하고, false일 경우 순회를 중지한다.
모든 자식 노드가 true인 경우 Sequence 노드도 true를 리턴하고,
false인 자식이 존재하는 경우 즉시 false를 리턴하고 종료한다.
ICompositeNode를 상속받는다.
[SelectorNode와 비슷하지만 순회 중지의 조건이 명확하게 다르다. : true를 탐색하는것과, false를 탐색하는 부분]
ParalleNode : ICompositeNode
자식 노드들의 실행 결과에 관계 없이 모든 자식 노드를 순회한다.
예시 코드
private INode _currentBehavior; private void MakeBehaviorNodes() { _currentBehavior = Selector ( Condition(CharacterIsDead), Condition(CharaterIsStunned), Condition(CharcterIsRolling), //위 조건 만족 시 모든 행동 불가능 //1.공격 Sequence ( Condition(CharacterIsBattleMode), Condition(CharacterIsGrounded), Condition(AttackKeyDown), Action(Attack), Action(PlayAttackAnimation) ), Condition(CharacterIsBinded), //속박 시 아래 행동 불가능 //2.점프 Sequence ( NotCondition(OnAttackCooldown), Condition(JumpKeyDown), Action(Jump), Action(PlayJmupAnimation) ), //3.구르기 Sequence ( Condition(RollKeyDown), Action(Roll), Action(PlayRollAnimation) ), //4.이동(WASD) Action(KeyboardMove) ); }
☆예시 코드 구조를 내 맘대로 간단하게 이해해보자
INode 형태의 현재 행동을 나타내는 변수에
BT 기법을 이용해 값을 할당하고 있다.
우선 Selector(SelectorNode)를 통해 모든 상태를 묶어주고
아래의 코드를 주르륵 실행시키도록 한다.
이때, Selector(SelectorNode) 는 하위 노드들에서 true인 값이 나오는 경우 즉시 종료하도록 해준다.
[현재 원하는 값을 서치하는 경우 아래는 무시]
그 후
조건식을 통한 반환을 주는
Condition(ConditionNode)를 입력하여
맨 먼저 모든 행동을 제한하는 상태를 먼저 체크하고
(여기서 해당 상태에 걸린다면 SelectorNode 는 종료될 것이다.)
다음으로 볼 부분은 Sequence(SequenceNode)로, 공격이다.
자식 노드들을 실행시키는데,
Condition 노드로 우선 공격이 가능한 상태인지 체크하고,
모든 Condition을 넘은 경우에만 Action(ActionNode)을 통해 실제로 행동을 실행시킨다.
[ Selector 는 true를 체크하지만 Sequence 는 false를 체크하므로 유의하자
공격 가능 여부를 체크하는 Condition들은 공격이 가능하다면 true를 반환해야 할 것이다.]
그 뒤 또 한번 Condition을 통해
아래의 행동에만 별개의 제한을 줄 수 있다.
예시의 경우 속박 Condition이 true인 경우, Selector가 중지되도록 해 놓았다.
다음 Sequence(SequenceNode)는 점프이다.
공격 Sequence(SequenceNode)와는 차이가 있는데
NotCondition 노드가 들어가있다.
아마 Condition이 반환하는 기준을 통일하기 위해 해당 노드를 추가적으로 작성한 듯
마찬가지로 조건 통과 후 Action을 통해 실제 행동을 실행한다.
구르기 Sequence(SequenceNode)는 위의 Sequence들과 완전 동일해서 그냥 넘어가겠다.
마지막으로 Sequence에서 벗어나 있는 Condition에만 영향을 받는
이동을 실행하는 Action을 작성하여 놓았다.
전체 글과 예시의 노드 이름과 클래스, 인터페이스들을 직관적으로 작성하여 놓았지만,
유니티나 C#에서 기본적으로 제공하는 코드들이 아니므로(이건 기법이다.)
사용 시 사용자가 용도와 역할에 맞게 다시 잘 작성해야 할 듯 하다.
예시 그림(여기의 상위에 Selector 노드(루트 노드)가 존재한다고 보면 될것같다.)
반응형'TIL' 카테고리의 다른 글
params(가변 인자 매개변수) (0) 2023.10.27 강의 - 디자인 패턴 - 빌더(빌드) 패턴 (0) 2023.10.27 RPC(원격 프로시저 호출 / Remote Procedure Calls) 란 무엇인가? (1) 2023.10.25 네트워크 게임을 개발하는데 필요한 이론적 배경-2 (0) 2023.10.24 네트워크 게임 개발 이론-1 (1) 2023.10.24