안녕하세요!
오늘은 네비게이션 기능을 개선했던 내용을 써보려 합니다.
저희가 만든 네비게이션 기능은 AI가 맵을 돌아다니고 플레이어를 쫓아오기 위해서 만든 그리드 기반 길찾기 시스템입니다.
동서남북 + 대각선 총 8방향으로 탐색하고 중간에 벽이나 넘을 수 없는 물체가 있는지 검사합니다.
디테일한 구현은 A*알고리즘을 참고하였습니다.
처음엔 땅과 언덕, 절벽이 전부였지만 새로 만드는 챕터에서 인간형 적이 등장하고, 밧줄이 레벨의 주요 요소로 쓰이게 됐습니다.
그래서 인간들이 밧줄을 타고 다니면 좋을 것 같다는 생각이 들었습니다.
그래서 밧줄을 점프해서 집거나 밧줄에서 다른 절벽으로 점프할 수 있는 위치를 미리 계산하기로 했습니다.
그리고 이런 점프포인트를 저장하기 위해 네비게이션 메쉬를 만들기로 했습니다.
1. 네비게이션 메쉬
유니티 커스텀 오버레이 기능으로 만들어진 데이터를 표시했고,
다양한 디버깅 기능을 추가해서 버그가 발생했을 때 추적이 쉽도록 하였습니다.
네비게이션 메쉬를 만든 목적인 밧줄의 경우는 위처럼 생성됩니다.
밧줄로 점프할 수 있는 위치를 계산하여 노드를 연결한 모습입니다.
이를 토대로 길찾기를 수행한 결과입니다.
얻은 경로는 각 노드별로 걸어서 갈지, 점프를 할지, 로프를 탈지등 이동 수단에 대한 정보를 포함합니다.
이후 네비게이터가 참고하게 됩니다.
2. 네비게이터
네비게이터는 길찾기 알고리즘에서 구한 경로를 따라가는 기능을 수행합니다.
다양한 상황에 대응해서 안정적으로 적을 따라가거나 특정 위치로 이동시켜주는 역할을 담당합니다.
그리고 이를 위해 다양한 모듈들이 구현되었습니다.
- Path Simplify
경로를 펴주는 모듈입니다.
알고리즘 특성상 노드의 위치를 단순히 잇는 방식이다보니 경로가 비효율적으로 생성되는데, 이걸 그대로 사용하면 AI 움직임이 어색해보이게 됩니다.
길을 펴기 위해 연속된 3개의 노드를 잡고 그 사이 중간 노드를 (벽에 부딪히지 않는) 최대한 직선상 위치로 이동시킵니다.
- 벽에 닿았을 때 평행방향 힘 주기
AI가 예기치 못하게 벽에 닿았을 때 정직하게 원래 경로방향으로 힘을 주게 되면 벽과 비벼지게 돼서 어색한 모습이 됩니다.
이 때 벽으로 향하는 힘을 틀어줘서 AI가 벽에 의해 움직임이 막히지 않도록 해주는 기능입니다.
- 떨어짐 방지 기능
저희 게임에는 절벽 지형이 많이 나오는데, AI 움직임에 기본적으로 물리를 사용하기 때문에 까딱하면 스스로 절벽으로 뛰어내리게 되는 경우가 생깁니다.
이를 방지하기 위해 네비게이션 매쉬에서 자신이 속한 땅의 다각형 모양을 통해 떨어질 수 있는 각도 범위를 계산합니다.
그리고 절벽지형에서 AI가 이동할 방향을 계산할 때 참고하게 됩니다.
- 동적인 길찾기 및 예외 동작들
경로를 방해하는 물체를 감지하고 여러가지 방법을 시도해보는 기능입니다.
예전에 만들었던 그리드 기반 길찾기를 방법 중 하나로 도입해 보았습니다.
이밖에도 멀티스레드 지원, 경로 재사용 기능으로 최적화를 진행하였으며 AI에서 중요한 요소인만큼 지속적으로 기능을 추가하고 버그를 수정해오고 있습니다.
마지막으로 AI가 로프를 사용하며 쫓아오는 모습입니다.
읽어주셔서 감사합니다!
오늘도 잘 보고가요 ㄹㅇ 고수
와 신기하네
와 쩐다
와 ㅋㅋ
어우야~
떨어짐 방지 기능 좋다! 이동시 저 각도 범위들을 제외하는 방법인가?
네 맞습니다! 방지 각도를 피하는 가장 가까운 각도로 움직이게 됩니다.
노드는 수작업으로 까시나요?
자동 생성 툴을 만들어서 쓰고 있습니다
왕고수ㄷㄷ..
역시 ai는 위대하다