언리얼엔진/블루프린트

언리얼 엔진 AI

season97 2023. 10. 10. 23:10

 블루프린트 AI 

 

ㆍ 3D월드에서 AI가 맵을 돌아다니게 하려면 터레인이나 NavMesh나 Navigation 정보가 필요하다.

 

ㆍ 맵에다가 위에 3종중에 하나를 심어줘야 한다.

 

ㆍ 지오메트리에 대해 심도있게 다룰게 아니라면 터레인은 상용엔진에서 다룰일은 많이 없다.

 

◈ Navigation 

 

상용 엔진에서 게임 오브젝트가 길을 찾을 때 사용한다.

→이는 AI 캐릭터가 움직이는 경로를 계획하고 장애물을 피하는 등의 동작을 가능하게 한다.

 

ㆍ 라이트맵과 유사한 구조를 가진다.

→ 게임환경의 3D 데이터를 분석해 AI 캐릭터가 안전하게 이동할 수 있는 영역과 그렇지 않은 영역을 구분한다.

 

ㆍ 네이베이션도 미리 Bake를 진행하고 시작하기 떄문에 길찾기 로직 치고는 그나마 가볍다.

 

ㆍ 단 맵의 크기가 커지거나 오브젝트가 많아지면 부하가 발생하기 시작한다.

→ 연산량이 증가하기 때문에 최적화에 신경쓰지 않으면 성능저하의 원인이 될 수 있다.

 

※ 언리얼엔진의 Navigation은 일반적으로 NavMesh와 함께 작동하여 게임환경 내에서 안전하게 이동할 수 있는 영역을 정의한다.

 

 

◈ NavMesh

 

ㆍ 게임 환경의 3D 공간을 2D평면으로 표현하여 AI 캐릭터가 움직일 수 있는 영역과 그렇지 않은 영역을 구분한다.

 

ㆍ 일반적으로 NavMesh는 간단한 폴리곤의 집합으로 표현되며, 각 폴리곤은 AI 캐릭터가 안전하게 걷거나 달릴 수 있는 "워크블" 영역이다

 

ㆍ 이후 Bake로 네비게이션 정보를 생성하고 생성된 정보를 바탕으로 AI캐릭터가 움직인다.

 

ㆍ NavMesh는 최적화 및 메모리 관리를 위해 남발하면 안된다. 언리얼 엔진에서는 각 레벨당 1~2개만 있는것이적당하다.

 

※ 내부적으로 내비게이션은 NavMesh와 같은 데이터 구조를 생성하며, 이 데티어 위에서 다익스트라나 A*와 같은 여러 길찾기 알고리즘이 살행된다.

 

※ 다익스트라?

 

ㆍ 가장 짧은 경로를 찾는 데 사용되는 그래프 검색 알고리즘

 

ㆍ 이 알고리즘은 모든 가중치가 양수인 그래프에서 최단경로를 찾는다.

 

 

▶ 언리얼에서 네비게이션 Bake 하기

NavMeshNoundsVolume 만들기

ㆍ 엑터 배치 탭에서 볼륨탭을 선택하고 NavMeshBoundVolume을 만들어줬다.

 

브러시 세팅

 

ㆍ 위치를 맞춰주고 브러시 세팅을 통해 맵 전체를 뒤덮어 주었다.

 

ㆍ Z값까지 맵을 덮을 수 있게 크기를 늘려줘야 한다고 한다.

 

베이크가 들어간 모습

ㆍ이후 'p' 버튼을 누르면 맵에 Bake가 된다. 

 

 

프로젝트 세팅

ㆍ 프로젝트 세팅에서 네비게이션 Mesh 탭을 보면 "셀 크기"와 "셀 높이" 조절을 할 수 있다.

 

ㆍ 수치를 낮출수록 정밀도가 올라가며 연산량이 증가한다.

 

ㆍ 정밀도가 올라가면 좁은 발판같은 경우도 Bake가 들어간다.

 

런타임에서 조절하는 법

ㆍ 네비게이션 메시 탭에서 설정중 런타임 생성이란 것이 있다.

 

ㆍ 이를 Static이 아닌  Dynamic으로 바꾸면 런타임 도중에도 실시간으로 움직이는 발판에 대해 네비게이션이 적용된다.

 

ㆍ 연산량이 정말 많으니 필요한 경우에만 사용하고 남발하지 않도록 주의하자.

 

 

 

 

 

▶ AI 로직을 구현하기 위한 객체들 (기능들)

 

ㆍ 언리얼에서 지원하는 고급 AI 기능들 → 세트로 다 같이 써야한다

 

1. Behavior Tree (행동트리)

 

ㆍ 적 캐릭터의 의사결정에 필요한 로직을 관리한다.

 

ㆍ 의사결정이라 함은 어떤 조건에 어떠한 액션을 취할것인지를 말한다.

 

ㆍ 각각의 노드가 조건(Condition)과 액션(Action)을 나태나며, 트리의 형태로 구성된다.

 

2. AI Controller

 

캐릭터와 행동트리를 연결하는 중간 역할을 한다.

 

ㆍ 행동 트리에서 만들어진 정보와 액션을 캐릭터에게 전달해 액션이 실제로 발생되게 한다.

 

ㆍ 일반적으로 PlayerController와 비슷하지만, 입력 정보가 플레이어가 아닌 AI로직에서 온다.

 

ㆍ Perception(인식) Pathfinding(경로 찾기) Decision Making(결정 매커니즘) 등 다양한 기능을 제공한다.

 

 

3. BlackBord

 

ㆍ Behavior Tree에서 사용되는 데이터를 저장하는 곳이다.

 

ㆍ Key-Value 형태로 데티러를 저장하며 행동트리의 여러 노드에서 공유해서 사용할 수 있다.

 

ㆍ 예를들어 순찰 위치, 체력, 상태 등의 정보를 저장하고 관리할 수 있다

 

ㆍ 쉽게말해 "뇌" 로 비유하면 된다.

 

 

▶ Pawn (폰)

 

일반적으로 게임 내 캐릭터를 나타내는데 사용되며, 플레리어나 AI를 제어할 수 있는 모든 엑터의 베이스 클래스 라고 할 수 있다.

 

ㆍ Pawn은 Controller 라는 개념을 통해 제어된다. PlayerController는 플레이어의 입력을 받아 처리하고,AIController는 AI 로직에 따라 작동한다

 

ㆍ 폰은 플레이어 또는 NPC형태로 게임의 AI제어를 받을 수 있다는 점이 엑터랑 다른점이다.

 

 

 

▶ 언리얼에서 적 캐릭터 블루프린터 만들고 AI적용시키기

Ue4ASP_Character 만들기

ㆍ 블루프린트 클래스를 만드는데 단순 액터로 만드는 것이 아닌 모든클래스 탭에서 미리 받아온 Ue4ASP_Character를 지정해 주어 만들어주었다.

 

ㆍ 이후 AI를 만들기 위해서는 Behavior Tree와 AI Controller와 BlackBord 3개가 필요하다고 했다.

 

블랙보드와 비헤이비어 트리

ㆍ 블랙보드와 비헤이비어 트리는 우클릭을 하고 인공지능탭에서 만들 수 있다.

 

 

AIController

ㆍ AIController는 우클릭 -> 블루프린트 -> 모든클래스 -> AiController를 검색해줘서 만들어주었다.

 

필요한 것들이 준비된 모습

 

ㆍ 우선 BP_EnemyCharactor을 들어가 주었다.

AI Controller 적용시키기

ㆍ AI 컨트롤러 클래스를 우리가 만든 EnemyController로 지정해주었다.

 

액터 배치 탭에 타깃 포인트

ㆍ 패트롤을 시키기 위해 타깃포인트를 2개 만들어주었다.

 

블랙보드

ㆍ 블랙보드에서 PatrollPoint 라는 오브젝트 키값을 만들고 베이스클래스를 Actor로 지정해 준다.

 

BP_EnemyCharactor 변수

ㆍ BP_EnemyCharactor 로 돌아와 위와같이 3개의 변수를 생성해 준다.

 

정찰 포인트 설정
다음 정찰 포인트 갱신

ㆍ 노드를 위 사진과 같이 연결해준 후 아래와 같이 PatrollPoint를 지정해주었다.

 

 

PatrollPoint지정

ㆍ 이러한 작업 이후 다음으로 행동트리 분기를 설정해야 한다.

 

▶ 행동 트리 분기들의 분기 노드

 

1. 셀렉터

 

ㆍ 아래쪽으로 연결된 모든 노드를 실행한다.

 

ㆍ 아래쪽으로 연결된 노드들은 자식이라고 하며 "왼쪽 -> 오른쪽" 으로 실행이 된다.

 

ㆍ 이 때 실행된 자식이 성공적으로 실행이 됐다면 그곳에서 실행을 멈추고 다음 노드를 실행하지 않는다.

 

ㆍ 셀렉터가 3개의 자식을 가지고 있다고 가정했을 때 가장 오른쪽에 있는 세번째 노드가 실행되려면 첫번째와 두번째 노드가 실행에 실패해야 한다.

 

※ if문이랑 실행방식이 비슷한듯??

 

 

2. 시퀀스

 

ㆍ 셀력터와는 반대로 모두 실행되며 모든 자식을 왼쪽에서 오른쪽으로 실행한다.

 

★ 셀렉터와의 차이점은 하나의 자식이라도 실행에 실패하면 바로 실행을 멈추고 시퀀스를 중지시킨다.

 

3. 테스크 노드

 

ㆍ 테스크 노드는 시각적으로 행동의 결과를 나타낸다.

 

ㆍ 행동 트리에서 가장 아래쪽에 위치하며 행동의 결과를 의미하기 때문에 아래쪽으로 더 이상 노드를 추가할 수 없다.

( 액션 노드 ) 

 

 

▶ 패트롤을 위해 행동 트리 분기 노드 실제 적용시키기.

위에서 설명한 행동 트리 노드

 

ㆍ 위와 같이 셀렉터 아래 시퀀스 아래 테스크 노드를 연결해주었다.

 

MoveTo노드 설정

ㆍ Move to 노드 설정이며 블랙보드 키를 우리가 만든 BlackBord에 있는 PatrollPoint로 지정해 주었다.

 

※ 허용 가능 반경을 늘리면 그만큼 범위가 유해진다고 한다. 

 

Wait설정

ㆍ 대기 시간을 설정해 줄 수 있으며 랜덤 편차에 입력한 값만큼 무작위로 +- 랜덤편차값 만큼의 시간을 수행한다.

 

행동트리 설정

ㆍ 마지막으로 EnemyController로 들어가 행동트리를 직접 설정해주면 된다.

 

결과물

 

ㆍ 위와 같은 설정을 해주면 드디어 AI가 맵에서 지정한 위치를 순찰한다!

 

 

※ 플레이어 위치 감지, 타깃포인트 여러개 조절 등의 작업들도 추후 다뤄봐야겠다.