언리얼 AI 시스템을 만들면서 1주일을 보내고 있습니다.

그동안 TIL작성도 없이 개발에만 몰두했습니다. 

지금 올리는 이 글은 TIL이 아닌 WIL입니다.

 

 

현재 진행중인 에디터유틸리를 이용한 레벨에 편의 기능 작업 중

 

 

TIL (Today I Learned) – Dynamic AI System (DAS) 코드 구조와 개념 정리

 

 

클래스 다이어그램

 

어떻게 상호작용하는 지 시퀀스 다이어그램

 

1. 시스템 동작 메커니즘 및 사용 기술/알고리즘

1.1 전체 메커니즘 개요

  1. 월드 레벨
    • UDASWorldSubsystem이 월드에 존재하는 모든 PathPoint, ActionPoint를 전역 관리합니다.
    • 에디터 상에서 ADASMapStreetPath(Spline)와 ADASPathSpot을 통해 여러 지점을 자동 생성/연결할 수 있습니다.
  2. AI 캐릭터
    • AI 캐릭터(또는 Pawn)는 UDASComponent를 소유하여 DAS 로직을 실행합니다.
    • Init(UBehaviorTree*)가 호출되면 Behavior Tree와 연계되어 ‘PathPoint 이동 → ActionPoint 실행 → 다음 지점 이동’ 과정을 제어합니다.
  3. PathPoint & ActionPoint
    • PathPoint(ADASPathPoint)는 AI가 이동할 지점(Spot 여러 개 가능).
    • ActionPoint(ADASActionPoint)는 실제 액션(애니메이션 재생, 함수 호출 등)을 모아둔 지점.
    • 두 지점에는 ConditionQuery가 붙어, “이 지점이 현재 실행 가능한가?”를 판단(쿨다운, 특정 태그/상태 등).
  4. ConditionQuery & ActionSelector
    • UDASConditionQuery: 여러 UDASCondition(추상 객체)을 AND/OR 형태로 묶어, 현재 상태 충족 여부를 종합.
      • Observer 패턴: OnConditionResultChanged 델리게이트로 조건이 실시간 변하면 AI 로직도 갱신 가능.
    • UDASActionSelector: 특정 PathPoint에 붙여 “해당 지점 도착 시 어느 ActionPoint들을 선택해 실행할 것인지”를 커스텀 로직으로 결정.
  5. 실행 흐름
    1. RunMode가 ExecutePathPoints인 경우:
      • ADASComponent가 ActivePathPoint로 이동 → 해당 지점의 ActionSelector로 액션포인트 큐를 구성 → 순차 실행 → 다음 PathPoint로 이동.
    2. RunMode가 ExecuteActionsFromSelector인 경우:
      • ActionSelector가 반환해주는 특정 ActionPoint들만 집중 실행 (순회 방식과는 별개).
  6. 비동기 실행
    • UAsyncActionHandlePointExecution, UAsyncActionHandleActionExecution 두 가지 Async Node를 두어, 블루프린트에서 “액션 완료 시점”을 이벤트로 처리 가능.
    • 내부적으로 AsyncExecute(비동기) → 완료 시 OnFinished 콜백 → 결과(성공/실패) 처리.

3.2 관련 기술 및 알고리즘

  1. Unreal Subsystem
    • UWorldSubsystem: 월드 단위 싱글턴처럼 동작하여, 전역 리소스(PathPoints/ActionPoints) 캐싱 및 제공.
    • 반복적으로 GetAllActorsOfClass를 호출하는 것보다 월등히 효율적.
  2. Condition 시스템(Observer 패턴)
    • UDASCondition: 추상 클래스. 각종 조건(체력, 태그 보유, 시간대, 쿨다운 등)에 맞춰 확장 가능.
    • UDASConditionQuery: 여러 UDASCondition을 합치는 래퍼 객체. Fulfilled 여부가 바뀌면 OnConditionResultChanged로 알림.
    • AND/OR 연산자( EDASOperator )로 조건을 조합 → AI는 이를 수신해 행동을 바꾼다.
  3. Path Solver / Graph 탐색
    • ADASPathPoint가 NextPathPoints / PreviousPathPoints로 그래프 형태를 이룬다.
    • 기본은 단순히 배열 중 무작위/순차로 다음 경로를 골라 이동하지만,
    • UDASPathSolver를 확장하면(예: A*나 Dijkstra 구현) 복잡한 경로 탐색도 가능.
  4. Behavior Tree & Blackboard
    • UDASComponent::Init(UBehaviorTree*)에서 AIController->RunBehaviorTree 실행.
    • Blackboard 키(GoalLocation, GoalRotation, PathPoint, ActionPoint 등)를 매번 갱신해 BTTask 또는 Decorator가 활용.
    • AI 이동은 MoveTo 노드가 GoalLocation(또는 PathPoint) 참조.
  5. 비동기 액션 처리
    • UDASAction: “Play Montage”, “Wait n seconds”, “Call Function” 등 구현체가 다양.
    • Async 노드(UAsyncActionHandleActionExecution)로 “액션 실행 → 완료/실패 대기” 블록을 블루프린트에서 직관적으로 구성.
  6. 에디터 확장 & 디버깅
    • UDASDeveloperSettings: 디버그 Draw(Line/Sphere/Arrow) 거리, 갱신 주기, 색상 등을 세팅.
    • DrawDebug 함수들(ADASBasePoint::DrawDebug, UDASPointVisComponent, UDASVisComponent)로 에디터/런타임에서 시각화.
    • ADASMapStreetPath, ADASPathSpot은 스플라인 편집 시 자동 Spot 액터를 생성하여 PathPoint를 빠르게 배치(레벨 디자이너 편의성).

정리

**Dynamic AI System(DAS)**는 언리얼 엔진의 Subsystem, Behavior Tree & Blackboard, Condition Observer 패턴, Async Actions 등 다양한 기능을 결합해 “경로 기반 이동” + “액션 포인트 실행” 로직을 모듈화 한 구조입니다.

  • UWorldSubsystem(UDASWorldSubsystem) : 전역적으로 PathPoint/ActionPoint 등록 & 검색
  • DASComponent(UDASComponent) : AI Pawn/Character에 붙어 “어떤 경로 지점으로 이동할지, 액션은 어떤 순서로 실행할지”를 통합 관리
  • PathPoint & ActionPoint : 맵 곳곳에 배치되어, AI가 순회하거나 액션을 수행하는 실제 지점
  • ConditionQuery : 실행 가능 여부를 동적으로 감지(쿨다운, 조건 충족 등)
  • ActionSelector : “경로 지점에 도착했을 때 어떤 액션 포인트를 사용할지” 결정
  • Async Action : 액션 실행이 완료될 때까지 비동기로 대기, 간단한 이벤트 바인딩 구조 제공

이로써 AI가 “지점 간 이동 → 행동 → 다시 이동”을 유연하게 제어할 수 있고, 재사용확장성을 높일 수 있게 됩니다.
디자이너/프로그래머는 Path/Action/Condition/Solver/Selector를 각각 필요에 맞춰 확장 구현하고, Behavior Tree와 매끄럽게 연동하여 다양한 AI 시나리오를 구현할 수 있습니다.

 

 

아래는 가이드 문서입니다.

1. DASWorldSubsystem

  • 역할: 월드에 존재하는 모든 ADASPathPoint(경로 지점)과 ADASActionPoint(액션 지점)를 전역적으로 관리하는 서브시스템.
  • 사용 의의:
    • 매번 GetAllActorsOfClass를 호출하기보다, AddPathPoint/RemovePathPoint, AddActionPoint/RemoveActionPoint로 등록/해제함으로써 성능을 최적화.
    • AI가 특정 지점(PathPoint/ActionPoint)을 찾을 때도 서브시스템의 캐시를 사용 (FindPathPointById, FindActionPointById 등).

2. DASTypes

  • EDASRunMode / EDASPathBehavior / EDASExecutionResult 등 각종 열거형(Enums) 정의.
  • AI의 실행 모드(경로 기반 혹은 액션 선택자 기반), 행동(경로 이동/액션 실행) 등 상태나 결과를 표현하는 값.
  • FDASSpot, FDASActionSelectorWrapper, FDASComponentSnapshot 같은 구조체(Struct)도 함께 선언:
    • FDASSpot: PathPoint 주변에 여러 Spot이 있고, AI가 정확히 그 위치(회전 포함)에 배치되도록 관리.
    • FDASComponentSnapshot: 저장/로드 기능을 위한 AI 상태 스냅샷 구조체(액션 큐, 실행 모드, 위치 등).

3. DASBluePrintFunctionLibrary

  • 기능: Blueprint에서 호출 가능하도록 만든 여러 유틸리티 함수 모음.
  • 주요 함수 예시:
    • CallFunctionByName: 문자열로 함수를 찾아 호출.
    • ClearTimersAndDelays: 특정 UObject가 사용 중인 타이머/Latent 액션(Delay 등)을 한 번에 정리.
    • SortPathPointsByDistance, SortActionPointsByDistance: 주어진 배열을 특정 위치와의 거리 기준으로 정렬.
    • FilterOutTakenActionPoints: 이미 다른 AI가 사용 중(taken)인 액션 포인트를 필터링.

4. DASAsyncNodes (UAsyncActionHandlePointExecution / UAsyncActionHandleActionExecution)

  • BlueprintAsyncActionBase를 상속받아, “Async”(비동기) 노드 형태로 액션 포인트를 실행.
  • ExecuteActionPoint / ExecuteAction 두 가지 방식:
    1. ExecuteActionPoint: ADASActionPoint를 비동기 실행 후 완료 결과(성공/실패)를 OnFinished로 반환.
    2. ExecuteAction: 개별 UDASAction 단위로 동일한 방식 수행.
  • 의의: 블루프린트에서 비동기 플로우(Async) 노드로 만들어, “Action이 끝나길 대기→다음 노드” 식의 직관적인 그래프 구성 가능.

5. ADASPathPoint / ADASActionPoint

  • ADASPathPoint(경로 포인트)
    • AI가 이동할 지점을 구성하는 액터.
    • NextPathPoints / PreviousPathPoints로 전/후진 경로가 연결되며, 경로 탐색 시 참고.
    • bReturnToPathPointAfterExecutingActions: 액션 수행 뒤 원래 지점으로 복귀할지 여부 등 옵션.
    • 여러 Spot(FDASSpot)을 가지고 있을 수 있어, AI가 PathPoint에 도달 시 정확히 어느 위치(Spot)로 배치될지 결정.
  • ADASActionPoint(액션 포인트)
    • Actions 배열을 가진 액터로, AI가 이 지점에 도달해 지정된 행동(몬타주 재생, 함수 호출 등)을 순차 실행.
    • “IsTaken” 상태로 여러 AI가 동시에 접근 못 하게 관리(“빼앗겼는지”를 확인).
    • 쿨다운(Cooldown)도 존재하여, 일정 시간 동안 재실행을 막을 수도 있음.

6. DASBasePoint

  • ADASPathPoint / ADASActionPoint의 부모 추상 클래스.
  • 공통 속성: PointId(GUID 식별자), ConditionQuery(조건), MoveSpeed, bRotateToPoint 등.
  • 주요 메서드:
    • CanRun(): 이 포인트가 사용 가능한지(조건 충족/쿨다운 등)를 체크.
    • DrawDebug(): 에디터나 디버그 모드에서 지점 시각화(라인, 아이콘, 텍스트 등).

7. DASCondition & DASConditionQuery

  • UDASCondition: “특정 조건”을 하나만 담당(예: 체력, 태그 보유 여부 등).
    • 내부적으로 IsConditionFulfilled_Internal을 구현해 조건 부합 여부를 판단.
    • OnConditionResultChanged 델리게이트를 통해 실시간 상태 변경 알림.
  • UDASConditionQuery: 여러 Condition들을 묶어 종합 결과를 확인(AND / OR 연산 등).
    • Initialize()로 각각의 Condition을 세팅/이벤트 등록.
    • IsConditionFulfilled() 호출 시 내부 Condition들의 결과를 종합.
    • OnConditionResultChanged 브로드캐스트로 “전체 조건 상태가 바뀐” 시점에 알림.

8. DASAction & DASActionSelector

  • UDASAction:
    • 액션 포인트 내부에 들어가는 “실행 단위” 객체.
    • Execute() → 비동기 완료( FinishExecute() ) 흐름.
    • 예: 애니메이션 재생, 대기, 함수 호출 등 다양하게 블루프린트에서 확장 가능.
  • UDASActionSelector:
    • 경로 포인트(ADASPathPoint)에 붙어서 “어떤 액션 포인트들을 실행할지” 결정하는 로직을 담당.
    • 예: GetActionPointsToExecute를 오버라이드하여, 태그 필터나 무작위 선택 등 커스텀.
    • “Instanced” 되어 PathPoint마다 별도 인스턴스(커스텀 로직) 사용 가능.

9. DASComponent

  • AI Pawn/Character에 붙는 핵심 컴포넌트.
  • RunMode(경로 기반 / 액션 선택자 기반)를 바탕으로 AI 동작 전체를 제어.
  • BehaviorTree와 연결하여:
    1. PathPoint 이동(ActivePathPoint)
    2. 액션 포인트(ActionPointsQueue) 실행
    3. 다음 PathPoint 이동 ...
  • 상태: PathBehavior(경로 이동 중인지, 액션 중인지 등), bIsMovingForwardAlongPath(앞/뒤 이동) 등.
  • 스냅샷(FDASComponentSnapshot) 기능으로 현재 상태를 저장/로드 가능 → 세이브/로드나 AI 풀링(오브젝트 풀)에 유용.

10. DASMapStreetPath / DASPathSpot

  • 스플라인을 이용해 지도(도로) 경로를 구성하는 액터(ADASMapStreetPath).
    • 에디터에서 Spline을 편집하면, 각 포인트마다 ADASPathSpot을 자동 생성/동기화.
    • ADASPathSpot에서 “SpawnDASBasePoint(예: ADASPathPoint)” 버튼으로 PathPoint를 에디터 상에서 생성.
    • Spot 간 연결(Next/Previous)을 자동 세팅해서, 실제 경로(ADASPathPoint)를 빠르게 만들 수 있음.

오늘 배운 핵심 정리

  1. DASWorldSubsystem이 전역으로 PathPoint/ActionPoint를 캐싱해둬서 AI가 손쉽게 참조 가능.
  2. DASComponent는 AI의 전체 흐름(경로 이동, 액션 실행, 스냅샷 관리)을 담당하고 Behavior Tree와 연동.
  3. PathPoint vs. ActionPoint:
    • PathPoint는 ‘이동 지점’, ActionPoint는 ‘행동 지점’.
    • 둘 다 Condition(쿨다운/태그 등)으로 실행 가능 여부를 제어하고, Spot을 통해 세밀한 위치 지정 가능.
  4. DASConditionQuery로 여러 조건을 묶고, AND/OR로 종합 판단.
  5. UDASAction / ActionSelector로 액션 로직을 확장 가능 (비동기 실행/완료).
  6. Debug & Editor:
    • DrawDebug 계열 함수와 VisComponent로 에디터/런타임에 시각화 지원.
    • DASDeveloperSettings에서 디버그 옵션(표시 거리, 화살표 애니메이션 등) 제어

+ Recent posts