개요
AI는 클라이언트가 아닌 Server에서 가지고 있는 지형 정보와 여러 Data(위치, 상태)등을 가지고 길 찾기를 실행한다.
A*
A*는 대표적인 길 찾기 알고리즘으로 1968년에 만들어진 알고리즘이다. A* 알고리즘은 아직 조사하지 않은 상태들(Open List)와 이미 조사한 상태들을 담은(Closed List)를 가지며 시작 지점으로부터 현재 상태에 이르는 가장 싼 비용 g(x)와 현재 상태로부터 가장 싼 비용 h(x) 이 둘을 더해서 가장 싼 추정 비용을 가지는 상태를 찾아서 이동하는 과정을 반복함으로 써 가장 싼 비용의 최종 경로를 찾는다. 또한 A*는 현명하게 사용하지 않으면 상당한 메모리와 상당히 많은(실시간 게임에서는 허용할 수 없을 정도의) CPU 시간을 잡아먹게 된다.
이러한 방법을 막기 위해 내가 생각하는 해결할 수 있는 방법은 다음과 같다.
1. A* 자체의 오버헤드는 막을 수 없기 때문에 A*를 실행할지 말지를 판단하게 한다.
2. 직선에 있는 목표에 대해서는 A*를 실행하지 않고 이동을 처리한다.
3. Navigation Mesh(맵 데이터)가 크면 많은 시간이 걸리기 때문에 탐색의 깊이를 조절한다.
InPutComponent
Server에 존재하는 모든 Monster들은 InputComponent의 인스텐스를 가진다. 이 Component는 디자인 패턴 중에 하나이다.(아래 링크 첨부)
주요 변수와 함수들의 설명은 다음과 같다.
이름 | 설명 |
MonsterState | 현재 Monster의 상태(FSM)를 가지는 Enum class형태의 변수이다. |
CAstar* | 길 찾기를 하는 AStar의 Handle 이다. |
AtomicBool | 길 찾기에서 발생하는 Data Race를 해결하기 위한 Flag 변수이다. 길찾기를 실행하고 있다면 다른 스레드가 들어가지 못하게 한다.( 이 변수는 바뀔 여지가 있다.) |
StartPathFind() | 현재 Monster의 상태에 따른 A*를 실행하는 함수이다. |
* 여기에 있는 변수와 함수들은 계속 Update를 진행하기 때문에 추가 삭제가 있을 수 있다. 앞으로 설명할 코드들도 동일하다
A*
A*를 직접 실행하는 Class의 변수와 함수들이다. 전체는 아니고 일부분 자른 모습이다.
주요 변수와 함수들의 설명은 다음과 같다.
이름 | 설명 |
AStar::OpenList | AStar의 아직 탐색하지 않은 리스트들을 가지는 변수이다. |
AStar::CloseList | AStar의 탐색을 진행한 리스트들을 가지는 변수이다. |
GetHeuristice() | 사전에 정의한 여러 휴리스틱 중에서 하나를 계산하고 그 값을 리턴해주는 함수이다. 여기서는 맨해튼 방식만 이용한다. |
* 좀 더 자세한 설명은 예전에 진행했던 쥐의 치즈 찾기 프로젝트에 자세한 설명이 있다.(아래 링크 첨부)
Navigation Data(지형 데이터)
지형 데이터를 가지는 Navigation 소스코드이다. 지형 데이터는 Cell 형식이며 각 Cell 마다 Type, Weight를 가진다.
지형 데이터는 이러한 형식으로 삽입을 하고 있는데 나중에 JSON으로 바꿀 예정이다.
실행 화면
벽 장애물을 피해서 플레이어에게 다가가는 것을 확인할 수 있다.
위 몬스터는 봤을 때 최단거리가 아닌 것처럼 보이지만 계산해보면 최단거리를 이동하는 것을 볼 수 있다. 하지만 몬스터가 마치 술 취해서 움직이는 듯한 움직임을 보여주기 때문에 보완이 필요해 보인다. 이러한 보완을 A*의 미시적 관점이라고 한다. 이 기법은 AI가 좀 더 자연스럽게 이동하도록 하는 기법이다.
다른 클라이언트에서 도 동일하게 A*를 실행하는 모습을 확인할 수 있다.
후기
A*를 Server에 돌려서 Monster의 이동을 확인해 보았다. AI는 내용이 길어질 거 같아서 두 개로 나눴다 하나는 현재 작성한 길 찾기 부분이고 다른 하나는 FSM 부분으로 나눠서 올릴 예정이다.
마지막에 몬스터 텍스쳐 방향이 조금 느리다는 버그 등 자잘한 버그들도 있고 아무래도 A*자체가 많은 자원을 소모하기 때문에 추후에 문제가 발생한다면 최적화를 진행할 예정이다. 각 구역마다 A*를 나눴기 때문에 큰 문제는 없을 거 같다.
A* 관련 및 디자인 패턴 글
[자료구조 알고리즘/탐색 알고리즘(Search)] - [알고리즘] A* 알고리즘
[자료구조 알고리즘/탐색 알고리즘(Search)] - [알고리즘] A* 치즈 찾기-PathFinding
[프로그래밍/디자인패턴] - [디자인패턴] 컴포넌트 패턴(Component Patterns)
리뉴얼 관련 글
--서버--
[portfolio] - [리뉴얼] 4- AcceptEx 및 이동 동기화
--클라이언트--
[portfolio] - [리뉴얼] 3- 공간 분할을 이용한 Sector Class
[portfolio] - [리뉴얼] 2- 경량 패턴을 이용한 World Class
[portfolio] - [리뉴얼] 1- 중재자 패턴을 이용한 Network Class
[portfolio] - [리뉴얼] 개요 및 목표(20.11.02 수정)
--리뉴얼 작업 전 포트폴리오
2019/12/16 - [portfolio] - DirectX & IOCP
* 리소스는 알피지 만들기 툴 리소스를 사용했으며 영리 목적으로 사용하지 않을 것입니다.
'portfolio' 카테고리의 다른 글
[리뉴얼] 7- AI의 FSM (0) | 2021.02.15 |
---|---|
[리뉴얼] 5- ViewList와 Sector (1) | 2020.11.18 |
[리뉴얼] 4- AcceptEx 및 이동 동기화 (0) | 2020.11.02 |
[리뉴얼] 3- 공간 분할을 이용한 Sector Class (0) | 2020.08.03 |
[리뉴얼] 2- 경량 패턴을 이용한 World Class (0) | 2020.07.27 |