info8995 님의 블로그

AI Perception을 이용한 시각 기반 플레이어 추적 시스템 구현 본문

TIL(Today I Learned)/Unreal Engine

AI Perception을 이용한 시각 기반 플레이어 추적 시스템 구현

info8995 2025. 5. 12. 20:07

✅ 오늘 학습한 내용 요약

오늘은 언리얼 엔진의 AI Perception 시스템 중 시각 감지(Sight) 기능을 중점적으로 학습하고, 이를 Behavior Tree와 연동하여 AI가 플레이어를 인식하고 추적하는 로직을 구현했다.
이 과정에서 AIController 내부의 시각 설정, 블랙보드 키 확장, 비헤이비어 트리 설계, Enum 상태 시스템 구성 등 여러 시스템을 종합적으로 설계하고 연동하는 과정을 실습했다.


🔧 주요 구현 내용 정리

1️⃣ 블랙보드 키 확장

AI의 감지 및 추적 상태를 저장하기 위해 다음과 같은 블랙보드 키를 새롭게 정의하고 사용했다:

  • TargetPlayer: Object 타입으로, 감지한 플레이어를 저장
  • CanSeePlayer: Boolean 타입으로, 현재 플레이어가 시야에 있는지 여부
  • LastSeenLocation: Vector 타입으로, 마지막으로 본 플레이어의 위치
  • SearchState: Enum 타입으로, 현재 AI의 상태 (Idle, Chasing 등)

이 키들은 Behavior Tree에서 분기 조건(Decorator)로도 활용되며, AIController에서 직접 값이 갱신되도록 구성하였다.


2️⃣ AIController에 시각 감지 설정

UAIPerceptionComponent와 UAISenseConfig_Sight를 활용하여 AI의 시각 능력을 설정했다.

  • 시야 반경 (SightRadius)은 1500.0f
  • 시야 상실 거리 (LoseSightRadius)는 2000.0f
  • 주변 시야각 (PeripheralVisionAngleDegrees)은 70도
  • 시야 감지 유지시간 (SetMaxAge)은 5초

해당 설정은 CoolGuyAIController 생성자에서 초기화하며, 인식 결과를 처리하는 콜백 함수 OnTargetPerceptionUpdated()에 바인딩했다.


3️⃣ 상태(Enum) 시스템 구성

AI의 상태를 명확히 관리하기 위해 C++과 블루프린트에서 모두 Enum을 정의하였다:

cpp
복사편집
UENUM(BlueprintType) enum class ESearchStateInternal : uint8 { Idle = 0, Investigating = 1, Chasing = 2, Searching = 3 };

에디터에서는 별도로 Blueprint Enumeration 리소스를 생성하여 SearchState 블랙보드 키와 연결하였으며, 시각 자극에 따라 이 상태값이 변화하도록 구현했다.


4️⃣ 감지 콜백 구현

OnTargetPerceptionUpdated() 함수 내에서 다음 로직을 처리했다:

  • 감지된 Actor가 플레이어라면
    • Stimulus.WasSuccessfullySensed() 값에 따라
      • 플레이어가 시야에 있을 경우: StartChasingPlayer() 호출
      • 시야에서 벗어난 경우: SearchState를 Investigating으로 변경 후 10초 후 StopChasingPlayer() 호출
  • 감지되지 않았거나 플레이어가 아닌 경우: 아무 동작 없음

또한 LastSeenLocation, CanSeePlayer, TargetPlayer 등의 키 값을 적절히 블랙보드에 기록해 Behavior Tree에서 활용 가능하게 했다.


5️⃣ Behavior Tree 설계

비헤이비어 트리에서는 Selector 노드를 중심으로 다음과 같은 분기 흐름을 구현했다:

  • 플레이어 추격 (Chasing)
    • 조건: CanSeePlayer == true && SearchState == Chasing
    • 행동: MoveTo(TargetPlayer) → Wait(1~3초)
  • 마지막 위치 추적 (Investigating)
    • 조건: CanSeePlayer == false && SearchState == Investigating
    • 행동: MoveTo(LastSeenLocation) → Wait(1~3초)

이러한 흐름을 통해 AI가 실시간으로 상태 전환 및 추적, 탐색을 할 수 있게 되었다.


📸 테스트 결과

  • 플레이어가 시야에 들어오면 Chasing 상태로 즉시 전환되어 추격을 시작한다.
  • 시야에서 벗어나면 Investigating 상태로 전환되어 마지막 본 위치로 이동하며 추적한다.
  • 일정 시간이 지나도 다시 감지하지 못하면 Idle 상태로 전환되어 추격을 중지한다.
  • 블랙보드의 TargetPlayer, CanSeePlayer, SearchState, LastSeenLocation 값이 실시간으로 갱신되는 것을 확인했다.

📝 마무리

이번 실습을 통해 언리얼 엔진의 AI Perception 시스템이 단순한 감지 기능에 그치지 않고, 감지된 자극의 유형을 분석하고 AI의 상태를 실시간으로 전환하는 복합적인 시스템이라는 점을 깊이 이해할 수 있었다.

특히 Behavior Tree, Blackboard, C++의 상태(Enum) 전환 로직이 유기적으로 연결되어야 AI가 자연스럽고 상황에 맞는 행동을 할 수 있다는 점이 인상 깊었다.
디버깅 중 Blackboard Key의 오타 하나로 AI가 정상 작동하지 않았던 경험을 통해, 키 이름의 정확성타입 일치의 중요성도 체감했다.

앞으로 이 시스템을 확장해 청각 자극 처리, 애니메이션 연동, 속도 변화 등 다양한 요소와 결합하면 훨씬 정교하고 반응성 높은 AI를 설계할 수 있을 것으로 기대된다.