본문 바로가기

기본 센서 시스템 구현 (시각, 청각)

AI Perception의 시각·청각 감각을 설정하고 감지 결과를 블랙보드에 반영해 플레이어 반응을 구현합니다.

앞 글의 추적 트리는 블랙보드의 TargetActor에 플레이어가 들어 있으면 쫓아갑니다. 그런데 그 값을 Get Player Character로 처음부터 채워 두면, AI는 벽 너머에 숨은 플레이어의 위치까지 늘 알고 있는 셈이 되어 은신이나 잠입이 성립하지 않습니다. AI가 실제로 보고 들은 것만 알게 하려면, 사람의 감각처럼 주변을 감지하고 그 결과만 블랙보드에 넘기는 장치가 필요합니다.

언리얼 엔진은 이 일을 AI Perception Component로 처리합니다. 이 글에서는 AI Perception이 제공하는 감각을 살펴보고, AI 컨트롤러에 시각과 청각을 설정한 뒤, 감지 결과를 감각별 규칙에 따라 블랙보드에 반영합니다. 그리고 플레이어가 감지되도록 자극원을 등록하고 소음을 보내, 보이는 경우와 소리만 들리는 경우에 AI가 다르게 반응하는지 확인합니다.


AI가 보고 듣게 하는 장치

AI 센서 시스템은 AI가 주변 환경에서 정보를 모아 게임플레이 로직에 필요한 데이터로 바꾸는 장치입니다. AI는 이 시스템으로 플레이어의 위치, 소리, 행동을 감지하고, 그 결과를 비헤이비어 트리의 판단에 씁니다.

센서 시스템이 있으면 AI가 게임 세계의 정보를 얻어 상황에 맞게 행동하고, 플레이어의 발소리나 총성, 시야에 들어오는 순간에 바로 반응하게 만들 수 있습니다. 은신, 잠입, 추격 같은 게임플레이도 결국 "AI가 무엇을 언제 알게 되는가"를 정하는 일이므로 센서 시스템 위에서 설계됩니다. 무엇보다 AI가 모든 것을 알고 움직이는 대신 실제로 주변을 인지하고 반응하는 것처럼 보이게 됩니다.

AI Perception Component와 감각

언리얼 엔진에서 센서 시스템의 중심은 AI Perception Component입니다. 이 컴포넌트는 여러 감각(sense)을 함께 관리하고, 감지한 정보를 이벤트로 전달해 AI 컨트롤러나 비헤이비어 트리에서 쓸 수 있게 합니다. 공식 문서는 시각, 청각, 피해, 접촉, 팀, 예측의 여섯 가지 감각을 소개하며, 이 글에서 쓰는 것과 함께 알아 둘 것은 다음과 같습니다.

  • Sight(시각): 정해진 시야각과 거리 안에서 플레이어나 다른 NPC 같은 액터가 보이는지 감지합니다.
  • Hearing(청각): 정해진 거리 안에서 발생한 발소리나 총성 같은 소음을 들을 수 있는지 감지합니다.
  • Damage(피해): AI가 피해를 입었을 때 이를 감지합니다.
  • Team(팀): 게임 로직이 보낸 팀 이벤트를 감지합니다. 아군, 중립, 적을 나누는 일은 이 감각이 아니라 따로 설정하는 소속(affiliation)과 팀 관계 구현이 정합니다.

이 목록과 헷갈리기 쉬운 것이 Dominant Sense입니다. Dominant Sense는 감각의 한 종류가 아니라 컴포넌트의 속성으로, 여러 감각이 같은 액터를 감지했을 때 그 액터의 위치를 어느 감각의 정보로 정할지를 지정합니다.


AI 컨트롤러에 시각과 청각 설정하기

이제 AI가 플레이어를 눈으로 보고, 플레이어가 내는 소리를 듣도록 설정해 보겠습니다. 필요한 블루프린트는 AI 폰(BP_EnemyCharacter), AI 컨트롤러(AIC_Enemy), 플레이어 캐릭터(BP_PlayerCharacter)입니다. AI Perception Component는 보통 AI 컨트롤러에 붙입니다.

AIC_Enemy를 열고 컴포넌트 패널의 Add 버튼에서 AI Perception을 검색해 추가합니다. 추가한 컴포넌트를 선택하고 디테일 패널의 Senses Config에서 + 버튼으로 AI Sight Config를 추가한 뒤 다음과 같이 설정합니다. 각 감각 설정의 Implementation 항목은 그 감각을 처리하는 클래스로, 기본값인 AISense_Sight를 그대로 둡니다.

항목값뜻
Sight Radius1500.0이 거리 안에서 새로 볼 수 있음
Lose Sight Radius2000.0이미 본 대상을 이 거리 밖에서 놓침
Peripheral Vision Half Angle Degrees60.0정면에서 한쪽으로 본 시야각. 전체 시야각은 120도
Detection By AffiliationDetect Neutrals 켜기어떤 소속의 대상을 감지할지

Detection By Affiliation에서 Detect Neutrals를 켜는 이유는, 팀 관계를 따로 구현하지 않으면 플레이어가 중립으로 분류되기 때문입니다. 이 실습에서는 중립을 감지한 뒤 플레이어 클래스로 캐스팅해 대상을 거르며, 아군과 적을 나누어 감지하려면 별도의 팀 관계를 구현합니다.

같은 방법으로 AI Hearing Config를 추가하고, Implementation은 기본값 AISense_Hearing으로 둔 채 Hearing Range를 1000.0으로, Detection By Affiliation은 시각과 같이 Detect Neutrals를 켭니다. 소리를 내는 쪽을 등록하는 일은 이 수신용 컴포넌트가 아니라 뒤에서 볼 플레이어 쪽의 AIPerceptionStimuliSource에서 합니다.

블랙보드에 키 추가하기

감지한 정보를 저장할 블랙보드 키를 준비합니다. BB_EnemyAI를 열고 Keys 패널의 New Key 버튼으로 키 두 개를 만듭니다. 첫째는 Vector 타입의 TargetLocation으로, 조사할 위치를 담습니다. 감지한 위치가 있을 때만 값을 넣고, 그 위치를 다 조사하면 Clear Value로 비웁니다. 둘째는 Object 타입의 TargetActor로, Base Class를 Actor로 설정해 지금 보이는 대상을 담습니다. 저장합니다.

감지 이벤트를 블랙보드로 옮기기

AI Perception 컴포넌트를 선택한 채 디테일 패널 아래쪽의 Events 영역에서 On Target Perception Updated 옆의 + 버튼을 눌러 이벤트 노드를 만듭니다. 이 이벤트는 AI가 어떤 액터를 감지하거나 그 감지 상태가 바뀔 때마다, 그 액터와 자극 정보(AIStimulus)를 함께 넘겨 줍니다.

이벤트의 Actor를 플레이어 클래스로 캐스팅해 플레이어인지 거르고, Stimulus는 Break AIStimulus로 나눠 감지에 성공했는지와 자극이 발생한 위치(Stimulus Location)를 꺼냅니다. 이 자극이 시각인지 청각인지는 Get Sense Class for Stimulus로 구분합니다. 블랙보드에 값을 쓸 때는 Get Blackboard로 블랙보드 컴포넌트를 얻어 Set Value as Object, Set Value as Vector, Clear Value를 호출합니다. 비헤이비어 트리의 노드 안에서 쓰는 Set Blackboard Value as... 노드와는 호출 대상이 다르므로 혼동하지 않습니다. 또 블랙보드는 비헤이비어 트리가 초기화된 뒤에 접근해야 하며, 그보다 먼저 감지 이벤트가 오는 경우를 처리하려면 초기화 뒤에 다시 반영하는 경로가 필요합니다.

어떤 감각으로 무엇을 갱신할지는 다음 그림의 규칙을 따릅니다.

감각별 Blackboard 갱신 정책

플레이어 한 명에 대해 선택한 사건의 추적 순서는 처음 시각 타깃이 없는 상태에서 청각 위치 기록→같은 플레이어 Sight 성공→Sight 상실이다. 청각 위치는 시각 타깃이 없을 때만 갱신하고, 시각 성공은 현재 타깃·확인 위치를 기록하며 상실은 타깃만 비우고 마지막 위치를 유지한다.

PROJECT POLICY · SIGHT / HEARING

감각별 증거를 나눠 Blackboard를 갱신합니다

아래는 플레이어 한 명을 대상으로 하는 예제의 처리 규칙입니다. 시각은 현재 타깃을, 청각은 조사할 위치를 갱신하며 서로의 유효한 증거를 함부로 지우지 않습니다.

핵심 관계동일 플레이어의 감각 사건에 대한 예제 정책이다. Sight 성공은 Actor와 관측 Location을 기록하고, Sight 상실은 해당 Actor만 비우며 마지막 Location은 유지한다. Hearing 성공은 시각 타깃이 없을 때만 소음 Location을 기록한다. 소음 기억의 수명 검사와 조사 완료 뒤 위치 해제는 별도 정책이다.Sight 성공Sight 상실Hearing 성공시각 타깃 없음Actor: 플레이어Location: 관측 위치Actor: 비움Location: 마지막 유지Actor: 설정 안 함Location: 소음 위치소음 기억 수명 검사조사 완료: 위치 해제
핵심 관계동일 플레이어의 감각 사건에 대한 예제 정책이다. Sight 성공은 Actor와 관측 Location을 기록하고, Sight 상실은 해당 Actor만 비우며 마지막 Location은 유지한다. Hearing 성공은 시각 타깃이 없을 때만 소음 Location을 기록한다. 소음 기억의 수명 검사와 조사 완료 뒤 위치 해제는 별도 정책이다.Sight성공Actor플레이어Location관측 위치Sight상실Actor비움Location마지막 유지Hearing성공타깃 없음Actor설정 안 함Location소음 위치소음 기억 수명 검사조사 완료: 위치 해제

동일 플레이어의 감각 사건에 대한 예제 정책이다. Sight 성공은 Actor와 관측 Location을 기록하고, Sight 상실은 해당 Actor만 비우며 마지막 Location은 유지한다. Hearing 성공은 시각 타깃이 없을 때만 소음 Location을 기록한다. 소음 기억의 수명 검사와 조사 완료 뒤 위치 해제는 별도 정책이다. Actor와 Location은 각각 TargetActor와 TargetLocation을 뜻합니다.

관계도 해설과 예제 원자료
감각별 Blackboard 갱신 정책
상황·검사기록할 값유지·해제 기준
시각 성공TargetActor에 플레이어, TargetLocation에 확인 위치를 기록합니다.현재 시각 타깃을 설정합니다.
시각 상실해당 TargetActor를 비웁니다.마지막 TargetLocation은 조사할 단서로 유지합니다.
청각 성공시각 타깃이 없을 때 TargetLocation에 Stimulus Location을 기록합니다.소리만으로 현재 시각 타깃을 만들지 않습니다.
소음 기억의 수명 검사해당 소음 기억의 유효시간을 검사합니다.보이는 타깃을 지우지 않습니다. 조사 완료 시 위치를 해제합니다.
상황·검사: 시각 성공
기록할 값: TargetActor에 플레이어, TargetLocation에 확인 위치를 기록합니다.
유지·해제 기준: 현재 시각 타깃을 설정합니다.
상황·검사: 시각 상실
기록할 값: 해당 TargetActor를 비웁니다.
유지·해제 기준: 마지막 TargetLocation은 조사할 단서로 유지합니다.
상황·검사: 청각 성공
기록할 값: 시각 타깃이 없을 때 TargetLocation에 Stimulus Location을 기록합니다.
유지·해제 기준: 소리만으로 현재 시각 타깃을 만들지 않습니다.
상황·검사: 소음 기억의 수명 검사
기록할 값: 해당 소음 기억의 유효시간을 검사합니다.
유지·해제 기준: 보이는 타깃을 지우지 않습니다. 조사 완료 시 위치를 해제합니다.

만료와 값 해제는 별도로 설계합니다

청각 기억의 유효시간을 검사하고 조사 완료 때 위치를 해제합니다. Max Age가 0이면 감각 자극은 나이 때문에 잊히지 않습니다. 감각 설정·Forget Stale Actors와 프로젝트의 기억 처리 정책을 함께 확인합니다.

이 예의 조건

  • 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
  • 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
관계도의 보충 설명
원 도표의 제목·노드·관계·조건·주석
범위원문
원 표의 셀해당 소음 기억의 유효 시간을 검사합니다.
본문·주석청각 기억의 유효 시간을 검사하고 조사 완료 때 위치를 해제합니다. Max Age가 0이면 감각 자극은 나이 때문에 잊히지 않습니다. 감각 설정·Forget Stale Actors와 프로젝트의 기억 처리 정책을 함께 확인합니다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
청각 사건

시각 타깃이 없는 상태에서 청각 감지가 성공하면 소음 위치를 기록한다.

  • 사전 조건·TargetActor: 시각 타깃 없음 · 미설정
  • TargetLocation: Stimulus Location (100, 200, 0) cm
  • 본문의 소음 위치 (100, 200, 0) cm를 기록한다. 시각 타깃이 없다는 조건이 필요하며 소음만으로 TargetActor를 설정하지 않는다.
시각 성공

같은 플레이어의 Sight 성공으로 Actor를 설정한다.

  • TargetActor: 보이는 플레이어
  • TargetLocation: 관측 위치
  • 감각별 증거의 의미를 구분한다.
시각 상실

Actor를 비우되 위치 기억을 정책에 맞게 유지한다.

  • TargetActor: 비움
  • TargetLocation: 기억 유지
  • 다른 감각의 유효 증거를 무조건 함께 지우지 않는다.

감각별 Blackboard 갱신 정책

플레이어 한 명에 대해 선택한 사건의 추적 순서는 처음 시각 타깃이 없는 상태에서 청각 위치 기록→같은 플레이어 Sight 성공→Sight 상실이다. 청각 위치는 시각 타깃이 없을 때만 갱신하고, 시각 성공은 현재 타깃·확인 위치를 기록하며 상실은 타깃만 비우고 마지막 위치를 유지한다.

PROJECT POLICY · SIGHT / HEARING

감각별 증거를 나눠 Blackboard를 갱신합니다

아래는 플레이어 한 명을 대상으로 하는 예제의 처리 규칙입니다. 시각은 현재 타깃을, 청각은 조사할 위치를 갱신하며 서로의 유효한 증거를 함부로 지우지 않습니다.

핵심 관계동일 플레이어의 감각 사건에 대한 예제 정책이다. Sight 성공은 Actor와 관측 Location을 기록하고, Sight 상실은 해당 Actor만 비우며 마지막 Location은 유지한다. Hearing 성공은 시각 타깃이 없을 때만 소음 Location을 기록한다. 소음 기억의 수명 검사와 조사 완료 뒤 위치 해제는 별도 정책이다.Sight 성공Sight 상실Hearing 성공시각 타깃 없음Actor: 플레이어Location: 관측 위치Actor: 비움Location: 마지막 유지Actor: 설정 안 함Location: 소음 위치소음 기억 수명 검사조사 완료: 위치 해제
핵심 관계동일 플레이어의 감각 사건에 대한 예제 정책이다. Sight 성공은 Actor와 관측 Location을 기록하고, Sight 상실은 해당 Actor만 비우며 마지막 Location은 유지한다. Hearing 성공은 시각 타깃이 없을 때만 소음 Location을 기록한다. 소음 기억의 수명 검사와 조사 완료 뒤 위치 해제는 별도 정책이다.Sight성공Actor플레이어Location관측 위치Sight상실Actor비움Location마지막 유지Hearing성공타깃 없음Actor설정 안 함Location소음 위치소음 기억 수명 검사조사 완료: 위치 해제

동일 플레이어의 감각 사건에 대한 예제 정책이다. Sight 성공은 Actor와 관측 Location을 기록하고, Sight 상실은 해당 Actor만 비우며 마지막 Location은 유지한다. Hearing 성공은 시각 타깃이 없을 때만 소음 Location을 기록한다. 소음 기억의 수명 검사와 조사 완료 뒤 위치 해제는 별도 정책이다. Actor와 Location은 각각 TargetActor와 TargetLocation을 뜻합니다.

관계도 해설과 예제 원자료
감각별 Blackboard 갱신 정책
상황·검사기록할 값유지·해제 기준
시각 성공TargetActor에 플레이어, TargetLocation에 확인 위치를 기록합니다.현재 시각 타깃을 설정합니다.
시각 상실해당 TargetActor를 비웁니다.마지막 TargetLocation은 조사할 단서로 유지합니다.
청각 성공시각 타깃이 없을 때 TargetLocation에 Stimulus Location을 기록합니다.소리만으로 현재 시각 타깃을 만들지 않습니다.
소음 기억의 수명 검사해당 소음 기억의 유효시간을 검사합니다.보이는 타깃을 지우지 않습니다. 조사 완료 시 위치를 해제합니다.
상황·검사: 시각 성공
기록할 값: TargetActor에 플레이어, TargetLocation에 확인 위치를 기록합니다.
유지·해제 기준: 현재 시각 타깃을 설정합니다.
상황·검사: 시각 상실
기록할 값: 해당 TargetActor를 비웁니다.
유지·해제 기준: 마지막 TargetLocation은 조사할 단서로 유지합니다.
상황·검사: 청각 성공
기록할 값: 시각 타깃이 없을 때 TargetLocation에 Stimulus Location을 기록합니다.
유지·해제 기준: 소리만으로 현재 시각 타깃을 만들지 않습니다.
상황·검사: 소음 기억의 수명 검사
기록할 값: 해당 소음 기억의 유효시간을 검사합니다.
유지·해제 기준: 보이는 타깃을 지우지 않습니다. 조사 완료 시 위치를 해제합니다.

만료와 값 해제는 별도로 설계합니다

청각 기억의 유효시간을 검사하고 조사 완료 때 위치를 해제합니다. Max Age가 0이면 감각 자극은 나이 때문에 잊히지 않습니다. 감각 설정·Forget Stale Actors와 프로젝트의 기억 처리 정책을 함께 확인합니다.

이 예의 조건

  • 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
  • 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.

관계도의 보충 설명

원 도표의 제목·노드·관계·조건·주석
범위원문
원 표의 셀해당 소음 기억의 유효 시간을 검사합니다.
본문·주석청각 기억의 유효 시간을 검사하고 조사 완료 때 위치를 해제합니다. Max Age가 0이면 감각 자극은 나이 때문에 잊히지 않습니다. 감각 설정·Forget Stale Actors와 프로젝트의 기억 처리 정책을 함께 확인합니다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
청각 사건

시각 타깃이 없는 상태에서 청각 감지가 성공하면 소음 위치를 기록한다.

  • 사전 조건·TargetActor: 시각 타깃 없음 · 미설정
  • TargetLocation: Stimulus Location (100, 200, 0) cm
  • 본문의 소음 위치 (100, 200, 0) cm를 기록한다. 시각 타깃이 없다는 조건이 필요하며 소음만으로 TargetActor를 설정하지 않는다.
시각 성공

같은 플레이어의 Sight 성공으로 Actor를 설정한다.

  • TargetActor: 보이는 플레이어
  • TargetLocation: 관측 위치
  • 감각별 증거의 의미를 구분한다.
시각 상실

Actor를 비우되 위치 기억을 정책에 맞게 유지한다.

  • TargetActor: 비움
  • TargetLocation: 기억 유지
  • 다른 감각의 유효 증거를 무조건 함께 지우지 않는다.

위 그림은 플레이어 한 명을 대상으로 하는 이 예제의 처리 규칙입니다. 그림의 Actor와 Location은 각각 TargetActor와 TargetLocation을 뜻합니다. 시각 감지에 성공하면 TargetActor에 플레이어를, TargetLocation에 확인한 위치를 기록해 현재 시각 타깃을 정합니다. 시각을 잃으면 그 TargetActor만 비우고, 마지막 TargetLocation은 조사할 단서로 남겨 둡니다. 청각 감지에 성공하면 시각 타깃이 없을 때만 TargetLocation에 Stimulus Location을 기록하며, 소리만으로 TargetActor를 만들지는 않습니다.

그림의 마지막 줄은 소음 기억의 수명과 위치를 비우는 일을 따로 다룹니다. 소음 기억이 유효한 시간을 검사하더라도 그 검사 때문에 지금 보이는 타깃을 지우지 않고, 위치는 조사를 마쳤을 때 비웁니다. 감각 설정의 Max Age가 0이면 자극이 시간이 지나도 잊히지 않으므로, 감각 설정과 Forget Stale Actors 설정, 그리고 프로젝트의 기억 처리 규칙을 함께 확인합니다.

단계 그림은 같은 규칙을 사건의 순서대로 보여 줍니다. 먼저 시각 타깃이 없는 상태에서 청각 감지가 성공해 소음 위치를 기록하고, 이어서 같은 플레이어가 시각으로 감지되어 TargetActor를 설정하며, 마지막으로 시각을 잃었을 때 TargetActor는 비우되 위치 기억은 규칙에 맞게 유지합니다.

이 규칙에서 중요한 점이 두 가지 있습니다. 첫째, 청각 이벤트의 위치는 Stimulus Location을 쓰며, 보이지 않는 액터의 현재 위치를 계속 읽어 쫓지 않습니다. 그렇게 하면 AI가 감지하지 않은 움직임까지 알게 됩니다. 둘째, 시각을 잃는 일과 소리를 듣는 일은 서로 다른 사건이므로 한 감각의 실패로 다른 감각의 상태까지 지우지 않습니다. 여러 대상을 다루도록 넓히려면 액터별 감각 상태와 목표의 우선순위를 따로 관리합니다. 연결을 마쳤으면 컴파일하고 저장합니다.


플레이어를 감지 대상으로 만들기

AI가 플레이어를 감지하려면 플레이어 캐릭터가 자극원(stimuli source)으로 등록되어 있어야 합니다. BP_PlayerCharacter를 열고 컴포넌트 패널의 Add 버튼에서 AIPerceptionStimuliSource를 검색해 추가합니다. 추가한 컴포넌트의 디테일 패널에서 Register as Source for Senses에 + 버튼으로 AISense_Sight와 AISense_Hearing을 차례로 추가하고, Auto Register as Source를 켭니다. 이 컴포넌트에는 "나를 봤다"거나 "내 소리를 들었다" 같은 이벤트가 따로 없으며, 감지 이벤트는 앞에서 본 것처럼 감지하는 쪽의 AI Perception에서 처리합니다.

소음 보내기

청각은 실제 오디오가 재생된다고 저절로 작동하지 않습니다. 발소리 노티파이나 무기 발사 이벤트처럼 소음이 나는 순간에 Report Noise Event를 호출해야 AI의 청각 감각에 자극이 생깁니다. Noise Location에는 소리가 난 위치를, Instigator에는 플레이어를, Loudness에는 1 같은 양수 세기를, Tag에는 소리를 구분할 이름을 넣습니다. Max Range와 감지하는 쪽의 Hearing Range도 함께 확인합니다. 매 Tick 호출하기보다 실제로 소음이 나는 순간에만 호출해야 불필요한 자극이 줄어듭니다. 컴파일하고 저장합니다.


감지 반응 확인하기

모든 블루프린트를 컴파일하고 저장한 뒤, 레벨에 BP_EnemyCharacter와 BP_PlayerCharacter를 배치하고 게임을 플레이합니다. 확인은 앞의 규칙을 하나씩 따라가며 합니다.

먼저 적의 시야 범위로 들어가 시각 감지에 성공했을 때 TargetLocation과 TargetActor가 함께 설정되는지 봅니다. 이어서 시야에서 벗어나면 TargetActor가 비워지고 마지막 위치는 남아 있는지 확인합니다. 그다음 시각 타깃이 없는 상태에서 소음 이벤트를 발생시키면 TargetLocation에 소음 위치만 기록되고 TargetActor는 설정되지 않아야 합니다. 이때 그냥 움직이거나 오디오만 재생하지 말고, 앞에서 연결한 Report Noise Event를 실제로 호출하는 행동을 써야 합니다.

On Target Perception Updated에 Print String을 연결해 두면 감지 여부를 화면에서 바로 볼 수 있습니다. 마지막으로 시각 감지가 일어나면 비헤이비어 트리가 플레이어를 쫓는 가지로 바뀌는지 확인합니다. 소리만 감지한 경우에는 플레이어 추적이 아니라 소음 위치를 조사하는 가지와 연결해야 합니다.


센서를 쓸 때 주의할 점

감지 반경을 너무 넓게 잡거나 많은 AI가 동시에 복잡한 감지를 하면 성능에 영향을 줄 수 있으므로, 게임에 필요한 만큼의 반경과 감지 빈도를 정합니다. 감지가 기대와 다를 때는 플레이 중에 작은따옴표(') 키로 게임플레이 디버거를 열고 숫자 패드 4를 눌러 Perception 정보를 표시합니다. 시야각과 거리, 감지된 위치가 그려지므로 설정이 의도와 맞는지 바로 볼 수 있으며, 입력 설정에 따라 키는 달라질 수 있습니다.

AI Perception은 팀 시스템과 연동해 아군과 적을 구별할 수 있고, 어떤 소속을 감지할지는 감각마다 Detection By Affiliation으로 정합니다. 다만 앞에서 말했듯 팀 관계를 따로 구현하지 않으면 대상이 중립으로 분류됩니다.

블랙보드를 갱신할 때는 타깃을 잃는 순간과 마지막 위치의 기억을 비우는 순간을 구분합니다. 감각의 Max Age가 0이면 자극을 시간이 지나도 잊지 않으므로, 시간이 지나면 잊게 하려면 Max Age와 Forget Stale Actors 같은 관련 설정을 함께 확인합니다.

센서 시스템은 AI에게 인지 능력을 주어 게임 세계에 반응하게 만듭니다. 비헤이비어 트리, EQS와 함께 쓰면 AI가 본 것과 들은 것에 따라 다르게 움직이는, 플레이어가 속이고 피할 수 있는 상대를 만들 수 있습니다.

더 깊이: 시야 판정을 바꾸는 나머지 설정

시각 설정에는 시야각과 거리 말고도 판정에 영향을 주는 값이 더 있습니다. AI Perception 문서에 따르면 Auto Success Range from Last Seen Location을 0보다 크게 두면, 이미 본 대상이 마지막으로 보인 위치에서 이 거리 안에 있는 동안에는 늘 보이는 것으로 처리합니다. Point of View Backward Offset은 시야 원뿔을 계산할 시점을 뒤로 물리는 거리이고, Near Clipping Radius와 함께 쓰면 바로 곁의 대상을 알아차리는 근접 감지이자 주변 시야처럼 동작합니다. 정면 시야각 밖에 있는 아주 가까운 플레이어를 놓치는 것이 문제라면 이 두 값을 살펴봅니다.

여러 감각이 같은 대상을 감지했을 때 어느 감각의 위치를 쓸지도 정할 수 있습니다. 컴포넌트의 Dominant Sense에 지정한 감각은 감지한 액터의 위치를 정할 때 다른 감각보다 우선합니다. 그리고 Detection by Affiliation이 쓰는 소속은 현재 C++로만 정의할 수 있어서, 문서는 블루프린트만 쓰는 경우 Detect Neutrals로 모든 액터를 감지한 뒤 태그로 걸러 내라고 안내합니다. 이 글의 실습에서 Detect Neutrals를 켜고 플레이어 클래스로 캐스팅해 확인한 것도 같은 제약에서 나온 방법입니다.


정리

  • AI Perception Component는 시각, 청각, 피해, 접촉, 팀, 예측 감각을 관리하며, Dominant Sense는 감각이 아니라 위치를 정할 때 우선할 감각을 지정하는 속성입니다.
  • 시각은 Sight Radius, Lose Sight Radius, Peripheral Vision Half Angle Degrees로, 청각은 Hearing Range로 범위를 정하며, 팀 관계가 없으면 Detect Neutrals를 켜야 플레이어를 감지합니다.
  • On Target Perception Updated에서 감각을 구분해, 시각은 TargetActor와 위치를, 청각은 시각 타깃이 없을 때 Stimulus Location만 기록합니다.
  • 플레이어는 AIPerceptionStimuliSource로 자극원에 등록하고, 소리는 Report Noise Event를 호출해야 청각 자극이 됩니다.
  • 시각 상실과 청각 갱신은 다른 사건이며, 감각 기억의 수명과 블랙보드 값을 비우는 시점도 따로 설계합니다.

연습 문제

1. 소리가 난 위치와 지금 위치

시각 타깃이 없는 상태에서, 플레이어가 월드 (100, 200, 0) cm에서 낸 소음을 감지했습니다. 그 뒤 플레이어는 보이지 않는 채 (900, 900, 0) cm로 이동했고 새 자극은 없습니다. 조사할 위치와 TargetActor는 어떤 값이어야 할까요? 그다음 시각 감지에 성공한 뒤 이전 소음의 기억이 만료되면, 보이는 타깃을 지워도 될까요?

해설 보기

조사할 위치는 Stimulus Location인 (100, 200, 0) cm이고, TargetActor는 설정하지 않은 상태로 둡니다. 보이지 않는 플레이어의 현재 좌표 (900, 900, 0)을 계속 읽으면, AI가 감지하지 않은 움직임까지 알게 되어 은신이 의미를 잃습니다.

시각 감지에 성공하면 시각 타깃을 설정하며, 이전 소음의 기억이 만료되었다는 이유만으로 그 시각 타깃을 지우지 않습니다. 소음 기억은 청각에 관한 일이고 시각 타깃은 시각에 관한 일이기 때문입니다. 또 Max Age에 따른 감각 기억과 블랙보드의 위치를 비우는 일은 저절로 같은 사건이 되지 않으므로, 이 예제의 "조사를 마치면 위치를 비운다"는 규칙도 함께 확인합니다.

2. 발소리를 듣지 못하는 적

플레이어 캐릭터에 발소리 사운드를 재생하는 노티파이를 넣었고, 적의 청각 Hearing Range도 1000으로 설정했습니다. 그런데 적 바로 옆을 뛰어다녀도 청각 감지가 한 번도 일어나지 않습니다. 무엇을 확인해야 할까요?

해설 보기

먼저 발소리 노티파이에서 사운드만 재생하고 있지 않은지 확인합니다. 오디오 재생은 청각 자극을 만들지 않으므로, 같은 시점에 Report Noise Event를 호출해야 합니다.

호출하고 있다면 Instigator에 플레이어가 들어가는지, Loudness가 양수인지, Max Range가 너무 작지 않은지를 봅니다. 감지하는 쪽에서는 청각 설정의 Detection By Affiliation에 Detect Neutrals가 켜져 있는지 확인합니다. 팀 관계를 구현하지 않았다면 플레이어는 중립으로 분류되므로, 이 항목이 꺼져 있으면 소음이 있어도 감지되지 않습니다.

3. 시야 거리와 시야각

이 글의 설정에서 적은 플레이어를 아직 보지 못했습니다. 플레이어가 적의 정면에서 70도 옆, 1200cm 거리에 서 있으면 보일까요? 또 정면 1400cm에서 한 번 보인 플레이어가 정면을 유지한 채 1800cm까지 물러나면 계속 보일까요? 처음부터 1800cm에 있던 플레이어는 어떨까요?

해설 보기

70도 옆의 플레이어는 보이지 않습니다. Peripheral Vision Half Angle Degrees가 60이므로 정면에서 양쪽으로 60도씩, 전체 120도 안만 볼 수 있고, 70도는 거리가 1200cm로 Sight Radius 안이더라도 시야각 밖입니다.

정면 1400cm에서 한 번 본 플레이어는 1800cm까지 물러나도 계속 보입니다. 이미 본 대상은 Lose Sight Radius인 2000cm 밖으로 나가야 놓치기 때문입니다. 반면 처음부터 1800cm에 있던 플레이어는 새로 볼 수 있는 거리인 Sight Radius 1500cm 밖이므로 감지되지 않습니다. 두 반경을 다르게 두면 기준 거리 근처에서 감지와 상실이 반복되는 일을 줄일 수 있습니다.

AI Perception의 감각 설정과 이벤트, 디버깅 방법은 언리얼 엔진 공식 문서의 AI Perception에서 확인할 수 있습니다.

다음 글 간단한 AI 의사결정 모델 구현에서는 지금까지 만든 센서, 블랙보드, 비헤이비어 트리, 내비게이션을 하나로 연결해 순찰, 감지, 추적, 공격, 탐색이 순환하는 AI를 완성합니다.