Game AI System

열수철·2025년 2월 4일

AI Pattern 및 의사결정 방법

게임 AI를 설계할 때, 단순히 “적이 플레이어를 발견 → 공격” 하는 것 이상으로,
다양한 상황에서 복합적인 의사결정을 처리해야 하는 경우가 많습니다. 이번 글에서는 현업 및 인디 개발에서 많이 사용되는 AI 패턴의사결정 기법을 정리해보겠습니다.


1. FSM(Finite State Machine) & HFSM(Hierarchical FSM)

1.1 개념

  • FSM(유한 상태 머신): 한 번에 하나의 상태에 머무르면서, 조건이 충족되면 다른 상태로 전환.
    예) Idle → Chase → Attack → Die
  • HFSM(계층적 상태 머신): 상태가 많아지면 상위/하위 상태로 나누어 관리해 복잡도를 줄이는 방식.
    예) CombatState (상위) 내부에 ChaseState, AttackState 등(하위)

1.2 장점

  • 직관적:
    • 상태 별로 “무엇을 하는지”가 코드 상에서 명확히 드러남
  • 구현 난이도 낮음:
    • 간단한 전투 AI(보스 몬스터, 적 캐릭터)에 빠르게 적용 가능
  • HFSM은 상태 폭증을 계층 구조로 나눠 처리하므로 어느 정도 규모 확장에 견딤

1.3 단점

  • 상태 폭발:
    • 상태/전이가 많아지면 if/else 혹은 switch가 대량 발생해 스파게티화될 위험
  • 전략·우선순위 결정이 많은 경우 한계:
    • AI가 여러 의사결정을 동적으로 해야 할 때는 FSM만으로는 관리가 힘들 수 있음
  • 복잡한 협업(디자이너/아티스트 참여)을 위해선 별도의 시각 툴이 필요

1.4 구현 특징

// 추상 State
public abstract class State<T>
{
    protected T owner;
    public State(T owner) { this.owner = owner; }

    public virtual void Enter() {}
    public virtual void Update() {}
    public virtual void Exit() {}
}


public class StateMachine<T>
{
    public State<T> CurrentState { get; private set; }
    private List<Transition<T>> transitions = new List<Transition<T>>();

    public StateMachine(State<T> initialState)
    {
        CurrentState = initialState;
        CurrentState.Enter();
    }

    public void AddTransition(Transition<T> transition)
    {
        transitions.Add(transition);
    }

    public void Update()
    {
        // 상위 FSM 전환 조건 확인
        foreach (var transition in transitions)
        {
            if (transition.From == CurrentState && transition.Condition())
            {
                CurrentState.Exit();
                CurrentState = transition.To;
                CurrentState.Enter();
                break;
            }
        }

        // 현재 상태의 Update (CompositeState라면, 내부에서 SubState도 처리)
        CurrentState.Update();
    }
}
  • 보통 상태 클래스상태 머신 클래스(현재 상태 관리, 전환 로직)를 분리
  • HFSM의 경우 상위 상태(CompositeState) 내부에 subState를 두어 재귀적으로 관리

2. Behaviour Tree(BT)

2.1 개념

  • 노드 기반 의사결정 트리. 루트 노드에서 자식 노드를 순회하며 조건(Decorator)과 행동(Task)을 수행.
    • 대표 노드: Selector, Sequence, Parallel, Decorator(조건부)
  • 시각 에디터(블루프린트, Behaviour Tree Editor 등)를 통해 블록 단위로 AI 동작을 구성 가능.

2.2 장점

  • 유연한 확장성:
    • 노드를 더 붙이기만 하면 새로운 행동·우선순위·조건을 쉽게 추가
  • 시각적 툴과 궁합이 좋음:
    • 디자이너나 기획자가 그래프 형태로 AI 동작을 조립 가능
  • 우선순위, 반복, 중단, 재시도 등 고급 기능을 지원하기 쉬움

2.3 단점

  • 초기 학습 곡선:
    • 노드 유형, Decorator, Service 등 구조를 이해해야 함
  • 단순 AI엔 오버엔지니어링이 될 수 있음
  • 노드 수 증가 시 트리 시각화가 복잡해질 수 있음

2.4 구현 특징

// Pseudo-code: Selector, Sequence, Action 노드 예시
public abstract class BTNode
{
    public abstract BTState Tick();
}

public class Selector : BTNode
{
    private List<BTNode> children;
    public override BTState Tick()
    {
        foreach (var child in children)
        {
            var result = child.Tick();
            if (result == BTState.SUCCESS)
                return BTState.SUCCESS;
        }
        return BTState.FAILURE;
    }
}
  • Tick() 반복호출로 노드 순회
  • Unity/Unreal 엔진에는 Behaviour Tree 시스템이나 플러그인, 시각 스크립팅 툴이 존재

3. GOAP (Goal-Oriented Action Planning)

3.1 개념

  • 목표(Goal) 달성을 위해, 현재 상황에서 유효한 액션(Action)들의 조합을 플래닝해 수행.
    • 예) “체력이 30% 미만 → (목표) 체력 회복 → (행동 계획) 포션 찾기 → 획득 → 사용”
  • STRIPS(Planning 알고리즘)에서 파생된 기법, 동적으로 액션 시퀀스를 구성

3.2 장점

  • 동적 대응력:
    • 환경 변화(자원 부족, 장애물 등)에도 새 계획을 수립
  • 재사용성:
    • 액션과 목표를 잘 정의하면, 다양한 캐릭터 AI에 적용 용이
  • 복잡 AI(특히 NPC, RTS 유닛 등)에 유리

3.3 단점

  • 구현 난이도:
    • 플래닝 알고리즘을 이해·구현해야 하고, 액션 간 조건/효과를 꼼꼼히 세팅해야 함
  • 실행 성능:
    • 액션/목표가 너무 많으면(거대 오픈월드), 계획 수립 연산량이 커질 수 있음

3.4 구현 특징

// Pseudo-code for GOAP
public class Action
{
    public Dictionary<string, bool> PreConditions;
    public Dictionary<string, bool> Effects;
    public float Cost;
    // 실행 로직 등
}

public class GoapAgent
{
    public List<Action> actions; 
    public Dictionary<string, bool> worldState;
    public List<string> goals;

    public void Plan() { 
        // 검색 알고리즘(A*, Dijkstra) 등으로 
        // PreConditions-Effects가 이어지는 Action 시퀀스 구성
    }
}
  • 액션(PreConditions, Effects), 플래너(검색)로 구성
  • RTS, 생존 게임, 오픈월드 NPC 등에 많이 응용

4. Utility AI

4.1 개념

  • 여러 행동(Action)에 대해 유틸리티 함수(가중치 계산)를 적용하고, “가장 높은 점수”를 가진 행동을 선택.
    • 예: 체력 낮음 → “회복” 행동의 Utility 점수 높음, 적 근접 → “공격” 점수 상승
  • 각 행동마다 “입력 변수(체력, 적 거리 등)에 따른 함수 곡선”을 정의.

4.2 장점

  • 동적인 우선순위:
    • 상태 폭발 없이도, 매 프레임 변화하는 상황에 유연 대응
  • 직관적 튜닝:
    • 곡선(예: 곡선 에디터)을 통해 각 변수와 행동의 상관관계를 눈으로 확인 가능
  • 사람처럼 보이는 행동:
    • 특정 조건만큼만 충족해도 행동을 바꾸는 식의 미세 조정 가능

4.3 단점

  • 함수 설계 난이도:
    • 변수마다 Utility를 어떻게 계산할지 잘못 설계하면, 예측 불가능한 행동 발생
  • 디버깅:
    • 왜 이 행동을 선택했는지 추적이 어려울 수 있음

4.4 구현 특징

public class UtilityAI
{
    public float health;
    public float enemyDistance;

    public float ComputeHealUtility() => Mathf.Clamp01(1 - (health / 100));
    public float ComputeAttackUtility() => Mathf.Clamp01((100 - enemyDistance) / 100);

    public void DecideAction()
    {
        float healScore = ComputeHealUtility();
        float attackScore = ComputeAttackUtility();

        if (healScore > attackScore)
            DoHeal();
        else
            DoAttack();
    }
}
  • 실제 프로젝트에선 각 행동마다 복합적인 변수/함수 적용
  • 전투, 생존, 택티컬FPS 등에서 동적 AI 구현 시 활용

5. Decision Tree(의사결정 트리)

5.1 개념

  • 분기 노드로 구성된 트리: 질문(조건)에 YES/NO로 따라가 최종 행동 결정
    • 예) “체력 < 30?” → YES: “도망”, NO: 다음 질문 “적이 근접?” → YES: “근접 공격” …
  • 구현 자체는 FSM보다 단순해 보이지만, 조건이 많아지면 트리가 복잡해질 수 있음

5.2 장점

  • 간단한 구조:
    • 논리적으로 분기만 나누면 되므로 스몰 프로젝트나 프로토타입에 적합
  • 직관적:
    • “조건 - 결과” 흐름이 눈에 잘 보임

5.3 단점

  • 규모 확장성 낮음:
    • 분기 노드가 늘어나면 관리가 힘들어짐(FSM과 유사 문제)
  • 복잡한 로직은 BT, HFSM 등에 비해 표현이 어려울 수 있음

5.4 구현 특징

public class DecisionTree
{
    public Node root;

    public void Update()
    {
        Node node = root;
        while (node is DecisionNode)
        {
            var decision = node as DecisionNode;
            node = decision.Decide() ? decision.trueNode : decision.falseNode;
        }
        (node as ActionNode).Act();
    }
}
  • 각각의 DecisionNode에 “조건 함수”를 정의해 YES/NO 분기
  • ActionNode에서 최종 행동 실행

6. Blackboard System

6.1 개념

  • 공유 데이터 저장소(블랙보드)에 여러 AI 모듈 또는 여러 에이전트가 접근해 상태 정보(플레이어 위치, 시간대, 위험 지표 등)를 확인·갱신.
  • Behaviour TreeGOAP에서도 블랙보드를 사용해 “환경 정보”를 공유하는 경우가 많음

6.2 장점

  • 협업 AI:
    • 여러 NPC가 같은 블랙보드를 참조하면, 서로의 행동을 동기화·조정하기 편리
  • 모듈성:
    • AI 로직(조건, 액션)과 데이터 저장소를 분리해, 확장 시 유리

6.3 단점

  • 설계 부주의 시 혼란:
    • 어떤 정보가 언제 갱신되는지 잘못 관리하면, 디버깅 어려움
  • 단일 캐릭터에선 이점이 크지 않을 수 있음(중복 구조)

6.4 구현 특징

public class Blackboard
{
    private Dictionary<string, object> data = new Dictionary<string, object>();

    public T GetValue<T>(string key) => (T)data[key];
    public void SetValue<T>(string key, T value) => data[key] = value;
}
  • AI마다 블랙보드 인스턴스를 참조 or 공유
  • BT, FSM, GOAP 등과 결합해 “공통 정보”를 조회·갱신

7. 기타/확장 기법

  1. HTN(Hierarchical Task Network)
    • GOAP와 유사하게 계획(Planning) 계통이지만, 더 구조화된 “작업 네트워크”로 세분화
  2. 네비게이션/이동(Pathfinding)
    • A*, NavMesh, Steering Behaviors 등은 의사결정과 별개로 “어떻게 이동할지” 처리
  3. 머신 러닝/딥러닝
    • 강화학습(RL), 딥러닝(Neural Networks)을 실제 게임 AI에 적용하는 시도(복잡도 높음, 특수 사례)

8. 어떤 기법을 언제 쓸까?

  1. FSM/HFSM

    • 보스 몬스터처럼 상태가 명확하거나, 적은 상태로도 충분한 소규모/중규모 프로젝트
    • 빠른 프로토타입, 전투 패턴 구현에 적합
  2. Behaviour Tree

    • 조건 분기가 다양하고, 시각 편집기로 직관적 구성을 선호
    • 멀티 행동 우선순위, 중단, 반복 등 복합 로직에 유리
  3. GOAP

    • 목표 지향이 중요한 환경, 동적 플래닝이 요구됨(오픈월드, RTS, 생존 AI)
    • NPC가 스스로 “어떻게 목표를 달성할지” 찾도록 해야 할 때
  4. Utility AI

    • 여러 변수를 종합해 매 프레임 “가장 가치 높은 행동”을 선택
    • 감정, 상황, 자원 등에 따라 유동적 대응을 원할 때
  5. Decision Tree

    • 극히 간단한 AI(분기 로직만 명확). 튜토리얼용, 소형 게임용
    • 빠르게 조건 분기만 구현해야 하는 상황
  6. Blackboard

    • 여러 AI 간 정보 공유가 필요, 또는 하나의 AI 내에서 모듈 간 데이터 교환
    • 다른 AI 패턴과 결합해 데이터 흐름을 정돈

9. 결론

게임 AI는 단순 FSM부터 Behaviour Tree, GOAP, Utility AI, Decision Tree, Blackboard 시스템까지, 다양한 패턴이 존재합니다.
각 기법은 고유한 강점제약이 있으며, 실제 프로젝트에서는 2개 이상의 기법을 혼합해서 쓰거나, 특정 부분만 활용하기도 합니다.

  1. 규모가 작고 패턴이 명확 → FSM/HFSM
  2. 다양한 분기, 시각 편집 필요Behaviour Tree
  3. 목표(Goal) 중심, 동적 계획GOAP
  4. 변수 기반 동적 우선순위Utility AI
  5. 단순 조건 분기Decision Tree
  6. 공유 데이터/협업 AIBlackboard

자신의 게임 장르, AI 복잡도, 팀 협업 방식을 고려하여 가장 적합한 패턴(또는 패턴 조합)을 선택하면, 유지보수성확장성을 모두 잡을 수 있을 것으로 기대됩니다.

“작은 프로젝트는 FSM, 어느 정도 이상이면 BT/GOAP/Utility AI 검토”가 흔한 흐름이며, 그 중에서도 “디자이너 주도 시 BT,” “목표 기반 AI 시 GOAP” 등으로 정리해서 적용해볼 수 있을 것 같습니다.

다음에 기회가 되면, AI 툴(시각 에디터, ScriptableObject 기반 설정)이나, 머신 러닝 RL 기법 등을 접목해보는 방법도 소개해드리겠습니다!

profile
그래픽스, 수학, 물리, 게임 만세

0개의 댓글