서론
비헤이비어 트리(Behavior Tree, BT)는 복잡한 행동을 제어하고 관리하는 데 사용되는 구조적 도구로, 주로 게임 AI, 로봇 공학, 그리고 다양한 인공지능 애플리케이션에서 사용된다. 비헤이비어 트리는 트리 구조로 이루어져 있으며, 각 노드는 특정한 행동이나 조건을 나타낸다. 이 트리는 가독성과 유지보수성을 높이기 위해 계층적으로 구성되어 있다.
비헤이비어 트리
비헤이비어 트리(Behavior Tree, BT)는 행동 트리를 구조를 활용한 AI이다. 이 덕분에 시각적인 이해 및 설계가 쉽고 모듈화가 잘 되어 있어서 유지 보수와 기능 추가에 있어 효율적이다. 또한 깊이 우선 탐색(왼쪽 -> 오른쪽)으로 로직이 흘러가다는 특징이 있다.
주요 개념
행동 트리를 구조에서 각 노드가 무엇을 의미하는 지 알아야 한다.
노드(Node)
- 루트 노드(Root Node): 트리의 최상위 노드로, 전체 비헤이비어 트리의 시작점
- 자식 노드(Child Nodes): 부모 노드로부터 파생된 노드들
- 리프 노드(Leaf Nodes): 더 이상 자식 노드가 없는 노드로, 실제 행동을 실행하거나 조건을 평가한다.
노드 타입(Node Types)
- 작업 노드(Task Nodes): 특정 행동을 수행한다.
- 예를 들어, "적을 공격한다"와 같은 구체적인 행동을 나타낸다.
- 조건 노드(Condition Nodes): 특정 조건을 평가한다.
- 예를 들어, "적이 보이는가?"와 같은 조건을 평가한다.
- 제어 노드(Control Nodes): 자식 노드들의 실행 순서를 제어한다.
- 주로 순차 노드(Sequence), 선택 노드(Selector), 병렬 노드(Parallel) 등이 있다.
- 합성 노드(Composite): 여러 자식이 있는 노드(Bunch Of Child)
- 단일 노드(Decorator): 자식 노드가 하나인 노드(Single Child, Condition Node)
제어 노드의 종류
- 순차 노드(Sequence Node)
- 자식 노드들을 순차적으로 실행한다.
- 하나의 자식 노드가 실패하면, 순차 노드는 실패로 종료된다.
- 모든 자식 노드가 성공하면, 순차 노드는 성공으로 종료된다.
- And gate와 비슷하게 작동
모든 자식 노드가 'SUCCESS' 반환해야 부모 노드에게 'SUCCESS' 반환한다. 만약 자식 노드 중 하나가 'FAILURE' or 'RUNNING' 반환한다면 부모 노드에게도 'FAILURE' or 'RUNNING' 반환한다. 즉, 자식 노드가 'SUCCESS'를 반환해야만 오른쪽으로 진행하게 된다. 만약 'Runnig'을 받으면 부모 노드로 돌아간다.
- 선택 노드(Selector Node)
- 자식 노드들을 순차적으로 실행한다.
- 하나의 자식 노드가 성공하면, 선택 노드는 성공으로 종료된다.
- 모든 자식 노드가 실패하면, 선택 노드는 실패로 종료된다.
- Or gate와 비슷하게 작동
자식 노드 중 하나가 'SUCCESS' 혹은 'RUNNING'을 반환하면 부모 노드에게도 'SUCCESS' 혹은 'RUNNING'을 반환한다. 이 때 부모 노드는 모든 자식 노드가 'FAILURE'를 반환해야 부모 노드에게 'FAILURE' 반환한다. 결국 선택 노드는 자식 노드의 결과가 어쨌던 간에 오른쪽으로 진행하게 된다. 만약 'Running'을 받으면 다음 깊이 노드로 진행한다.
- 병렬 노드(Parallel Node)
- 여러 자식 노드를 동시에 실행한다.
- 성공/실패 조건은 설정에 따라 다르다.
- 예를 들어, 모든 자식 노드가 성공해야 병렬 노드가 성공할 수도 있고, 하나의 자식 노드만 성공해도 병렬 노드가 성공할 수 있다.
평가 결과
'평가'의 결과는 성공(Success), 실패(Failure), 작동중(Running) 이렇게 총 3가지 상태가 있다. 그리고 평가 결과는 부모 노드에 전달하여 다른 노드 이동하는 데에 사용된다.
비헤이비어 트리의 장점
- 모듈성(Modularity): 각 행동과 조건을 독립적으로 정의할 수 있어 재사용과 유지보수가 용이하다.
- 가독성(Readability): 트리 구조 덕분에 행동의 흐름을 시각적으로 쉽게 이해할 수 있다.
- 확장성(Scalability): 새로운 행동이나 조건을 추가하기 용이하며, 트리 구조를 확장하여 복잡한 행동을 관리할 수 있다.
- 디버깅 용이성(Debuggability): 트리 구조를 통해 각 행동의 실행 경로를 쉽게 추적할 수 있어 디버깅이 용이하다.
예시
다음은 게임에서 플레이어와 상호작용하는 NPC(Non-Player Character)의 행동의 비헤이비어 트리에 대한 간단한 예시이다.
이 예시에서는 루트 노드 아래에 선택 노드가 있으며, 선택 노드 아래에 세 개의 순차 노드가 있는 형태이다.
- 첫 번째 순차 노드는 적이 보이는지 조건을 평가하고, 보인다면 병렬 노드를 실행한다.
- 병렬 노드는 모든 자식 노드가 성공해야 성공한다. 여기에는 두 개의 자식 노드가 있다.
- 첫 번째 자식 노드는 순차 노드로, 적이 사정거리에 있는지 확인한 후 공격한다.
- 두 번째 자식 노드는 적에게 이동하는 작업을 수행한다.
- 병렬 노드는 모든 자식 노드가 성공해야 성공한다. 여기에는 두 개의 자식 노드가 있다.
- 두 번째 순차 노드는 건강 상태가 낮은지 평가하고, 낮다면 도망가는 행동을 수행한다.
- 세 번째 순차 노드는 순찰이 필요한지 평가하고, 필요하다면 병렬 노드를 실행한다.
- 병렬 노드는 하나의 자식 노드만 성공해도 성공한다. 여기에는 세 개의 자식 노드가 있다.
- 각각의 자식 노드는 다른 순찰 경로를 따른다.
트리 구조 설명
- 루트 노드(Root Node): 트리의 시작점이다.
- 선택 노드(Selector Node): 세 개의 순차 노드 중 하나라도 성공하면 선택 노드는 성공으로 종료된다.
- 순차 노드(Sequence Node): 자식 노드들을 순차적으로 실행하며, 하나의 자식 노드가 실패하면 순차 노드는 실패로 종료된다.
- 조건 노드(Condition Node): 특정 조건을 평가한다.
- `IsEnemyVisible`: 적이 보이는지 평가.
- `IsInRange`: 적이 공격 사정거리에 있는지 평가.
- `IsHealthLow`: 건강 상태가 낮은지 평가.
- `IsPatrolNeeded`: 순찰이 필요한지 평가.
- 작업 노드(Task Node): 특정 행동을 수행한다.
- `AttackEnemy`: 적을 공격.
- `MoveToEnemy`: 적에게 이동.
- `Flee`: 도망.
- `PatrolRoute1`, `PatrolRoute2`, `PatrolRoute3`: 각각의 순찰 경로를 따름.
- 병렬 노드(Parallel Node): 여러 자식 노드를 동시에 실행하며, 성공/실패 조건은 설정에 따라 다르다.
- 첫 번째 병렬 노드: 모든 자식 노드가 성공해야 성공.
- 두 번째 병렬 노드: 하나의 자식 노드만 성공해도 성공.
이 구조를 통해 NPC는 다양한 상황에서 적절한 행동을 취할 수 있으며, 트리의 계층적 구조 덕분에 복잡한 행동을 체계적으로 관리할 수 있다.
주섬주섬
- 언리얼엔진에서는 기본 지원, 유니티에서는 에셋을 구매해서 이용할 수 있다. 그러나 나는 유니티에서 돈을 아끼기 위해 직접 구현해 졸업 작품을 만들었던 경험이 있다. 나름 인공지능 중에서 쉬운 편이기에 쉽게 만들 수 있을 것이다. 개발 코드는 블로그에 있지만 비공개를 할 것이니 댓글을 달아도 알려주지 않을 겁니다.
- 사람들이 반농담으로 "AI는 수많은 IF문으로 이루어진 프로그램이다"라고 한다. 직접 구현을 해보니 다른 AI보다 더 이 부분에 공감하였다.
- 트리는 다양한 사이트 및 툴즈를 통해 쉽게 만들 수 있다.
참고
'컴퓨터공학 > AI' 카테고리의 다른 글
비헤이비어트리(Behavior tree) C# 구현 (0) | 2024.07.18 |
---|---|
인공지능 8. RNN (1) | 2024.07.07 |
인공지능 7. 자연어 처리(NLP) (0) | 2024.05.07 |
인공지능 6. CNN (0) | 2024.04.25 |
인공지능 5. DNN (1) | 2024.04.19 |
댓글