게임 속 AI 캐릭터가 똑똑하게 행동하려면 상황에 맞는 의사결정이 필요합니다. 이를 위해 널리 쓰이는 방법 중 하나가 **행동 트리(Behavior Tree)**입니다. 행동 트리는 AI가 단계별로 계획된 행동을 수행하도록 돕는 구조로, 상황에 따라 다양한 반응을 이끌어낼 수 있습니다. 특히, Unity에서 행동 트리를 커스텀하게 구현해 사용하면 더 복잡하고 유연한 AI를 설계할 수 있습니다.
이 글에서는 행동 트리의 기본 개념부터 Unity에서의 구현 방법, 그리고 다양한 예제 코드까지 다뤄 AI NPC에게 지능적인 행동을 부여하는 방법을 소개드리겠습니다.
1. 행동 트리란?
행동 트리는 게임 AI의 행동을 트리 형태로 구조화해 단계적이고 우선순위에 맞는 행동을 수행하도록 하는 설계 패턴입니다. 이 패턴은 상위 노드에서 하위 노드로 연결되는 트리 형태로 구성되며, AI 캐릭터가 상황에 맞는 행동을 유연하게 결정할 수 있게 합니다.
- 선택 노드(Selector Node): 여러 자식 노드 중 하나의 행동을 선택하여 실행합니다.
- 순서 노드(Sequence Node): 순차적으로 실행할 행동들을 정의합니다.
- 조건 노드(Condition Node): 특정 조건을 검사하여 조건에 맞을 경우에만 다음 노드로 이동합니다.
2. Unity에서 행동 트리 구조 설계하기
Unity에서 행동 트리를 구현하려면, 각 노드와 이를 제어할 트리 구조를 관리하는 노드 클래스와 트리 클래스를 설계해야 합니다. 기본적으로 IAction 인터페이스를 정의하여 각 행동이 실행될 때마다 해당 인터페이스를 따르도록 구현하는 방법을 소개드립니다.
public interface IAction {
bool Execute(); // 실행 결과에 따라 성공(true) 또는 실패(false)를 반환합니다.
}
public class SelectorNode : IAction {
private List<IAction> actions;
public SelectorNode(List<IAction> actions) {
this.actions = actions;
}
public bool Execute() {
foreach (var action in actions) {
if (action.Execute()) {
return true; // 자식 노드 중 하나가 성공하면 멈춤
}
}
return false;
}
}
이와 같은 기본적인 SelectorNode는 여러 행동 중 하나라도 성공하면 동작을 멈추고, 그렇지 않으면 실패로 반환합니다. 이 패턴을 응용해 SequenceNode와 ConditionNode를 추가하여 복잡한 트리를 구성할 수 있습니다.
3. 상황에 따른 행동 트리 적용 예제
NPC가 플레이어를 추적하고, 장애물이 있을 때는 우회하며, 체력이 낮을 때는 회복하는 행동 트리를 예제로 들어 보겠습니다.
- Selector Node: 행동을 고르는 루트 노드
- ConditionNode (체력 낮음): 체력이 낮으면 회복
- Sequence Node (장애물 회피 후 추적): 장애물이 있을 경우 회피 후 플레이어 추적
이러한 트리를 통해 AI가 상황별로 다른 동작을 하게 만들어주는 것이 핵심입니다.
4. 커스텀 행동 트리 코드 예제
이번에는 좀 더 구체적인 예제 코드로 추적 행동과 회피 행동을 나눠서 구성해 보겠습니다.
public class FollowPlayerAction : IAction {
private Transform player;
private Transform npc;
public FollowPlayerAction(Transform player, Transform npc) {
this.player = player;
this.npc = npc;
}
public bool Execute() {
// 플레이어를 향해 이동
npc.position = Vector3.MoveTowards(npc.position, player.position, 0.1f);
return Vector3.Distance(npc.position, player.position) > 1f;
}
}
public class AvoidObstacleAction : IAction {
private Transform npc;
private Transform obstacle;
public AvoidObstacleAction(Transform npc, Transform obstacle) {
this.npc = npc;
this.obstacle = obstacle;
}
public bool Execute() {
// 장애물을 피해서 이동
Vector3 avoidDir = npc.position - obstacle.position;
npc.position += avoidDir.normalized * 0.1f;
return true;
}
}
이 코드에서 FollowPlayerAction
은 AI가 플레이어를 향해 이동하도록 설정합니다. AvoidObstacleAction
은 장애물이 있을 때 AI가 피하는 동작을 수행합니다. 이를 조합하여 트리를 구성하면, AI가 장애물이 있을 때는 피하고, 그렇지 않으면 플레이어를 추적하는 행동을 하게 됩니다.
5. 마치며
이렇게 행동 트리를 사용하면 Unity에서 더 지능적이고 유연한 AI를 구축할 수 있습니다. 특히 적 NPC나 동료 AI의 행동 패턴을 설정할 때 매우 유용합니다. 다양한 행동을 노드로 추가하고, 이를 트리 구조로 관리하면 복잡한 상황에서도 원하는 결과를 얻을 수 있습니다.
이제 여러분만의 AI 행동 트리를 설계하여 더욱 스마트한 NPC를 구현해 보시기 바랍니다!