최근 치이카와포켓이란 모바일 방치형 게임을 하고 있는데, 해당 게임이 2D 그래픽이고 많이 드러나는 게임 형식인데 반해 다른 게임들에 비해 렉이 많이 걸려서 왜 렉이 많이 걸릴까에 대한 이유를 생각해보았다.
0. 개요
1. 이유
2. 후기
0. 개요
게임을 플레이하다가 캐릭터 스탯 업데이트, 미니게임을 진행할 때에 딜레이가 생겨서 해당 부분 외 다른 이슈가 있는지, 해당 이슈는 왜 발생하는지에 대해 간단히 글을 써보았다.
1. 사례와 이유
* 로딩 지연
= 앱 실행 직후, 화면 전환할 경우(메인창에서 미니 게임, 캐릭터 스탯 창으로 이동할 경우), 광고 시청 후 UI 업데이트 등에서 딜레이를 느꼈다.
=> 초기 로딩 시간의 경우, 무분별한 전체 리소스 동기 로드가 문제라고 생각한다. 게임 시작할 때 필수 리소스만 선별하는 방법보다 딜레이가 길어지기 때문이다. 초기 로딩 시간을 길게 해서 리소스들을 전부 받아놓아 화면 전환 시 딜레이가 적게 발생하려는 의도인 것 같지만, 딜레이는 꾸준히 발생해서 적절하게 문제를 해결한 방법인지는 의문이다.
해당 문제를 해결하기 위해서는 일단 비동기 로딩으로 초기 에셋 로드를 분산시켜 놓는게 좋지 않을까라는 생각이 든다.
(Unity Addressables를 이용한다.)
* 데이터 업데이트 딜레이
= 캐릭터 스탯을 업데이트할 경우 또는 광고를 보고 리워드를 적용할 경우, 딜레이가 발생한다.
=> 플레이어의 모든 데이터를 플레이어가 상호작용하는 즉시 서버로 보내서 딜레이가 발생하는 것 같다. 이 부분은 클라단에서 처리할 데이터와 서버단에서 처리할 데이터를 분리하고, 상호작용할 때마다 서버로 데이터를 보내는 것이 아닌 일정 횟수만큼 받은 뒤 보내는 등 서버와의 통신 방식을 바꿔서 해결해야 할 것 같다는 생각이다.
* 프레임 드랍
= 게임이 멈추고 입력을 받지 못해 게임 진행이 끊기는 사례가 종종 있었다. (필자는 미니게임에서 겪음)
- GC 스파이크
=> 일정 간격으로 GC.Collect()가 실행되고, 한 프레임당 7ms 안팎의 드랍이 발생한다.
매 프레임 혹은 게임 로직에서 new, LINQ 등이 힙을 팽창시켜 GC가 빈번하게 동작하기 때문이다.
=> 오브젝트 풀링 도입, Embrace.io의 가비지 컬렉션 최적화 기법 적용 등의 방법이 있다.
* 과도한 드로우콜로 인한 GPU 병목
= 각 스프라이트가 별도 메터리얼로 배치되어 배칭이 어렵다.
=> 스트라이트를 통합해 텍스쳐 아틀라스 생성, 머터리얼 공유, 유니티 매뉴얼의 드로우콜 배칭 기법 적용
이외에는 위쪽에서 이야기한 에셋 번들 로드로 인한 문제를 Addressable에서 핵심 부분만 초기 로드 후 나머지는 비동기로 로드하는 것으로 해결하기, 동기적 리소스 로드로 인한 입력 부재 문제는 InstantiateAsync를 사용하고 완료 콜백에서 활성화해 프레임 분산 로드로 해결하는 방법 등이 있다.
2. 후기
찾아보면서 나도 단순히 게임에 대해 아쉬워만 한 것이 아니라 다양한 것을 알아가는 데 도움이 되었다. Embrace.io의 GC 최적화 기법은 좀 더 찾아봐서 따로 게시글을 써도 좋을 것 같다.