Posts 유니티 - 비헤이비어 트리(Behavior Tree)
Post
Cancel

유니티 - 비헤이비어 트리(Behavior Tree)

개념


  • FSM (Finite State Machine)의 단점을 보완하기 위해 만들어진 기법
  • FSM에서는 상태 전이 조건을 모두 각각의 상태에서 검사하지만, BT에서는 상태 동작 뿐만 아니라 전이 조건도 노드로 관리한다.
  • 노드 그래프를 통해 시각화하거나 params, 빌더 패턴 등을 활용하여 스크립트 내에서도 가독성 좋게 구성할 수 있다.
  • 기본적으로 Leaf, Decorator, Composite 노드를 기반으로 하며, 구현은 많이 다를 수 있다.
    • Leaf : 동작을 수행하는 노드. 대표적으로 Action 또는 Task 노드가 있다.
    • Decorator : 다른 노드에 조건을 붙여 수식하는 노드
    • Composite : 자식 노드들을 가지며, 자식들을 순회하거나 선택하는 역할을 수행하는 노드


노드 구성


  • 모든 노드는 실행의 결과로 true 또는 false를 리턴한다.
  • Decorator는 가독성을 위해 Composite와 Leaf들의 구성으로 대체하였다.


[1] 인터페이스

  • INode
    • 최상위 노드 클래스
    • bool Run(); 메소드를 가진다.
  • ILeafNode : INode
    • 트리의 각 말단을 이루는 주요 수행 노드
    • Action 또는 Condition이 해당된다.
  • IDecoratorNode : INode
    • 다른 노드들을 수식하여 동작 조건을 지정하는 노드
  • ICompositeNode : INode
    • 자식들을 순회하기 위한 노드
    • 인터페이스 구현 시 List ChildList 멤버를 작성한다.


[2] 클래스

  • ActionNode : ILeafNode
    • 주요 동작을 수행하는 역할을 하며, 무조건 true를 리턴한다.
  • ConditionNode : ILeafNode
    • 조건식을 검사하여, 그 결과를 리턴한다.
  • NotConditionNode : ILeafNode
    • 조건식의 결과를 반대로 리턴한다.
  • SelectorNode : ICompositeNode
    • 자식들 중 true인 노드를 만날 때까지 차례대로 순회한다.
    • 자식이 false일 경우 계속해서 다음 자식 노드를 실행하고, true일 경우 순회를 중지한다.
    • 모든 자식 노드가 false일 경우 Selector 노드도 false를 리턴하며, true인 자식 노드를 만난 경우 즉시 true를 리턴하고 종료한다.
  • SequenceNode : ICompositeNode
    • 자식들 중 false인 노드를 만날 때까지 차례대로 순회한다.
    • 자식이 true일 경우 계속해서 다음 자식 노드를 실행하고, false일 경우 순회를 중지한다.
    • 모든 자식 노드가 true인 경우 Sequence 노드도 true를 리턴하며, false인 자식이 존재하는 경우 즉시 false를 리턴하고 종료한다.
  • ParallelNode : ICompositeNode
    • 자식 노드들의 실행 결과에 관계 없이 모든 자식 노드를 순회한다.


예시 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
private INode _currentBehavior;

private void MakeBehaviorNodes()
{
    _currentBehavior =
        Selector
        (
            Condition(CharacterIsDead),
            Condition(CharacterIsStunned),
            Condition(CharacterIsRolling),
            // 위 조건 만족 시 모든 행동 불가

            // 1. 공격
            Sequence
            (
                Condition(CharacterIsBattleMode),
                Condition(CharacterIsGrounded),
                Condition(AttackKeyDown),
                Action(Attack),
                Action(PlayAttackAnimation)
            ),

            Condition(CharacterIsBinded),
            // 속박 시 아래 행동 불가

            // 2. 점프
            Sequence
            (
                NotCondition(OnAttackCooldown),
                Condition(JumpKeyDown),
                Action(Jump),
                Action(PlayJumpAnimation),
            ),

            // 3. 구르기
            Sequence
            (
                Condition(RollKeyDown),
                Action(Roll),
                Action(PlayRollAnimation)
            ),

            // 4. WASD 이동
            Action(KeyboardMove)
        );
}


Source Code



Download


This post is licensed under CC BY 4.0 by the author.