상세 컨텐츠

본문 제목

[Unity] 리소스 최적화

Unity

by 메타샤워 2023. 7. 19. 15:33

본문

○ 이미지 가로세로 사이즈는 무조건 2의 제곱 ( Power of Two) 

 

게임에서 사용하는 이미지 가소 세로 가이즈는 무조건 2의 제곱으로 되어야 한다.

컴퓨터에서 이미지를 사용할 때에는 개념적으로 
(1) 디스크에서 이미지 불러오기 
(2) 이미지 압축 포멧 압축 해제
(3) 1024 X  1024 X 32 비트 메모리 블록에 해당 이미지 할당 
의 과정을 거친다.
 
1024 X  1024 X 32 비트 RGBA 기준으로 이미지를 압축한 png 용량은 313KB에 불과 하다. 하지만 압축을 해제하면 메모리상 이미지는 4MB가 된다.  2048 X 2048 이라면 16MB에 이른다.
 
이렇게 가로세로 사이즈가 2의 제곱으로 된 이미지가 아닌 경우에는 상당한 메모리 낭비가 일어나게 된다. 예를 들어 900 X 900 사이즈 이미지가 있다고 하자. 메모리상에서 900 X 900 사이즈 이미지를 로드할 때 해당 이미지를 똑같이 1024 X 1024 로 변환해 다시 메모리에 저장하게 된다. 다시 말해 거의 배에 가까운 이미지 메모리가 낭비되는 것이다.
 
이런 이유 때문에 UNITY 3D를 비롯한여러 게임 개발 엔진에서 아틀라스 (Atlas) 라는 리소스 단위를 사용하게 된다. 

이미지를 2의 제곱방식으로 바꿔서 항상 활용하라

 

 

○ 메모리 사용량 프로파일링을 직접 해보면...

 

 

이번에는 게임 리소스를 최적화 할때 직접 간단한 프로파일러를 돌려보겠다. 

 

현재 Scene에 있는 모든 이미지 리소스를 모두 조사해 개별 객체가 얼마나 메모리를 차지하고 있는데 체크해 큰순서대로 나열한다.
var sortedAll = FindObjectsOfTypeIncludingAssets(typeof(Texture2D)).OrderBy(go=>
 
Profiler.GetRuntimeMemorySize(go)).ToList();

이 명령으로 현재 모든 텍스처2D 오브젝트를 구할 수 있다. 또 메모리 크기 순서대로 정렬한 상태로 리스트가 나오게 된다. 그렇다면 모든 텍스처2D 리스트를 출력해보자

 

var sortedAll = FindObjectsOfTypeIncludingAssets(type).OrderBy(go=>
 
Profiler.GetRuntimeMemorySize(go)).ToList();
 
StringBuilder sb = new StringBuilder(“”);
int memTexture = 0;
for(int i = sortedAll.Count-1;i>=0;i–){
    if(!sortedAll[i].name.StartsWith(“d_”)){
        memTexture += Profiler.GetRuntimeMemorySize(sortedAll[i]);
        sb.Append(type.ToString());
        sb.Append(” Size#”);
        sb.Append(sortedAll.Count – i);
        sb.Append(” : “);
        sb.Append(sortedAll[i].name);
        sb.Append(” / Instance ID : “);
        sb.Append(sortedAll[i].GetInstanceID());
        sb.Append(” / Mem : “);
        sb.Append(Profiler.GetRuntimeMemorySize(sortedAll[i]).ToString());
        sb.Append(“B / Total : “);
        sb.Append(memTexture/1024);
        sb.Append(“KB “);
        sb.Append(“\n”);
    }
}
Debug.Log(“Texture2D Inspect: “+sb.ToString());

 

이렇게 간단한 c# 코드로 된 프로파일러를 돌려보면 현재 씬에서 어떤 텍스처2D가 괴물같이 많은 메모리를 먹고 있는지 눈으로 확인할 수 있다. 안드로이드 빌드라면 안드로드 DDMS의 로그캣으로 로그를 확인할 수있다. 여러 테스트기기에서 해당 로그를 직접확인해보고 싶다면 서버에 로그를 남기는 방식도 가능하겟다.

 

 

○텍스처 하나하나 최적화로 마무리

 

마지막은 가장 많은 메모리를 먹고 있는 텍스처 부터 작은것까지 하나하나 최적화를 해나간다. 먼저 쓸데없이 큰 공간을 차지하는 아틀라스의 경우는 몇 개를 묶어 하나로 만들어 남은 여백을 줄인다. 달므으로 필요없는 이미지는 삭제한다.
 
눈에 크게 보이지 않는 이미지가 너무 고해상도인 경우 화질은 낮춰서 다시 임포틑 하는 것도 잊지 말아야 한다. png의 경우 포토샵 플러그인을 통해서 이미지를 압축해 다시 임포트 한다.
 
오디오 파일은 모바일에서 스테레오 모드가 의미없으니 모두 92kb 모노로 인코딩하도록 설정한다. 이 설정은 유니티 엔진에서 가능하다. 또 이미지가 여러번 로딩되지 않게 Singleton 패턴을 활욜해보자.
 
물론 위와 같이 리소스와 메모리 최적화 방법은 단편적인 솔류션이다. 하지만 게임에서 가장 많은 용량과 메모리를 차지하는 이미지 이미지 리소스 최적화에선 아주 기본적인 단계이다.

 

관련글 더보기