▶ 블루프린트 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 하기
ㆍ 엑터 배치 탭에서 볼륨탭을 선택하고 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를 지정해 주어 만들어주었다.
ㆍ 이후 AI를 만들기 위해서는 Behavior Tree와 AI Controller와 BlackBord 3개가 필요하다고 했다.
ㆍ 블랙보드와 비헤이비어 트리는 우클릭을 하고 인공지능탭에서 만들 수 있다.
ㆍ AIController는 우클릭 -> 블루프린트 -> 모든클래스 -> AiController를 검색해줘서 만들어주었다.
ㆍ 우선 BP_EnemyCharactor을 들어가 주었다.
ㆍ AI 컨트롤러 클래스를 우리가 만든 EnemyController로 지정해주었다.
ㆍ 패트롤을 시키기 위해 타깃포인트를 2개 만들어주었다.
ㆍ 블랙보드에서 PatrollPoint 라는 오브젝트 키값을 만들고 베이스클래스를 Actor로 지정해 준다.
ㆍ BP_EnemyCharactor 로 돌아와 위와같이 3개의 변수를 생성해 준다.
ㆍ 노드를 위 사진과 같이 연결해준 후 아래와 같이 PatrollPoint를 지정해주었다.
ㆍ 이러한 작업 이후 다음으로 행동트리 분기를 설정해야 한다.
▶ 행동 트리 분기들의 분기 노드
1. 셀렉터
ㆍ 아래쪽으로 연결된 모든 노드를 실행한다.
ㆍ 아래쪽으로 연결된 노드들은 자식이라고 하며 "왼쪽 -> 오른쪽" 으로 실행이 된다.
ㆍ 이 때 실행된 자식이 성공적으로 실행이 됐다면 그곳에서 실행을 멈추고 다음 노드를 실행하지 않는다.
ㆍ 셀렉터가 3개의 자식을 가지고 있다고 가정했을 때 가장 오른쪽에 있는 세번째 노드가 실행되려면 첫번째와 두번째 노드가 실행에 실패해야 한다.
※ if문이랑 실행방식이 비슷한듯??
2. 시퀀스
ㆍ 셀력터와는 반대로 모두 실행되며 모든 자식을 왼쪽에서 오른쪽으로 실행한다.
★ 셀렉터와의 차이점은 하나의 자식이라도 실행에 실패하면 바로 실행을 멈추고 시퀀스를 중지시킨다.
3. 테스크 노드
ㆍ 테스크 노드는 시각적으로 행동의 결과를 나타낸다.
ㆍ 행동 트리에서 가장 아래쪽에 위치하며 행동의 결과를 의미하기 때문에 아래쪽으로 더 이상 노드를 추가할 수 없다.
( 액션 노드 )
▶ 패트롤을 위해 행동 트리 분기 노드 실제 적용시키기.
ㆍ 위와 같이 셀렉터 아래 시퀀스 아래 테스크 노드를 연결해주었다.
ㆍ Move to 노드 설정이며 블랙보드 키를 우리가 만든 BlackBord에 있는 PatrollPoint로 지정해 주었다.
※ 허용 가능 반경을 늘리면 그만큼 범위가 유해진다고 한다.
ㆍ 대기 시간을 설정해 줄 수 있으며 랜덤 편차에 입력한 값만큼 무작위로 +- 랜덤편차값 만큼의 시간을 수행한다.
ㆍ 마지막으로 EnemyController로 들어가 행동트리를 직접 설정해주면 된다.
ㆍ 위와 같은 설정을 해주면 드디어 AI가 맵에서 지정한 위치를 순찰한다!
※ 플레이어 위치 감지, 타깃포인트 여러개 조절 등의 작업들도 추후 다뤄봐야겠다.
'언리얼엔진 > 블루프린트' 카테고리의 다른 글
델리게이트 (0) | 2023.10.12 |
---|---|
AI 플레이어 감지하기 (0) | 2023.10.12 |
UI를 이용한 플레이어 스탯 연동 (0) | 2023.10.08 |
보간과 타임라인을 이용한 움직이는 발판 (0) | 2023.10.08 |
엑터 패트롤 시키기 (0) | 2023.10.08 |