지난 포스팅에서는 수정된 A*알고리즘을 이용해서 글라이딩, 벽타기 상황이 고려된 길안내를 구현하는 과정을 다뤘습니다. 이번 포스티에서는 해당 알고리즘을 위해서 생성되는 Voxel의 최적화 문제와 해결과정에 대해서 다뤄보도록 하겠습니다.
CPathFinding이라는 플러그인에서 제공하는 Voxel생성방식은 언리얼의 BeginPlay
이벤트에서 모든 로직을 처리합니다. 즉, 런타임에 모든 복셀정보를 메모리에 새롭게 동적할당하는 방식을 사용합니다. 그래서 초기 생성시간이 아주 오래걸릴 수 있는 문제점이 있었습니다. 문제상황을 확인하기 위해서 한 가지 실험을 진행했습니다.
실험환경 :0.5km 0.5km 0.1km 공간에 2m 2m 2m 사이즈의 복셀데이터를 생성하는 테스트 레벨(복셀 3,125,000개)
실험결과 : 복셀 생성 시간(30초)
이러한 복셀 생성을 매번 게임시작할때마다 반복하게 된다면, 게이머 입장에서는 아주 답답한 게임이 될 것입니다.
멘토링에서 복셀 데이터를 디스크에 저장하는 baking
기능을 구현하면 해결할 수 있다는 아이디어를 얻었습니다. 매번 게임을 플레이할때마다 동적생성하지 않고 개발단계에서 미리 데이터를 파일화한 다음에 게임을 플레이할때는 로딩만 해서 빠르게 이용하자는 아이디어 였습니다.
다음과 같은 로직으로 해당 기능을 구현했습니다
1. 복셀 volume에서 baking데이터 사용을 체크한경우
- baking데이터가 있는 경우
→별도의 생성없이 단순 로딩
- 없는 경우
→ baking데이터 생성하기
2. 복셀 volume에서 baking데이터 사용을 체크해제한 경우
- 기존과 같이 동적할당방식 유지
복셀데이터들은 uint32
의 일차원 배열데이터들로 구성되어 있었기에
배열의 크기 + 각 배열의 저장된 uint32
값들로 저장데이터를 구성했고
해당 데이터를 로딩하는 코드도 작성했습니다.
실험환경 :0.5km 0.5km 0.1km 공간에 2m 2m 2m 사이즈의 복셀데이터를 생성하는 테스트 레벨(복셀 3,125,000개)
실험결과(Baking없이 동적생성) : 30초 소요
실험결과(이미 생성된 Baking데이터를 로딩) : 3초 소요
구현 결과 상당한 시간 절약을 할 수 있었습니다. 하지만, 싱글스레드로 일차원 배열을 로딩하는데다가 48MB라는 큰 사이즈로 인해서 아직도 시간이 꽤 소요되는 것을 확인할 수 있었습니다. 이 문제는 멀티스레드 기술을 활용해서 해결할 수 있을 것입니다.