반응형

UI 리소스 최적화로 메모리와 용량 최적화 잡기


최근 게임을 제작할 때, PC를 타깃으로 한 평범한 수준의 게임은 유저들의 평균적인 메모리 사양이 4~8GB 가량 되기 때문에 메모리에 크게 구애받는 일은 적은 편이지만, 모바일을 타깃으로 하거나, PC나 콘솔 타깃이더라도 고사양의 게임은 메모리에 대한 최적화가 필요하다.

특히 모바일의 경우, 하이엔드 모델은 3~4GB 이상의 넉넉한 메모리를 지원하는 모델이지만, 대다수의 사용자들이 사용하는 보급형 모델은 1~2GB 수준으로 메모리 최적화를 고려하지 않고 게임을 만들었다면, 저사양의 유저들은 게임을 원활하게 게임을 플레이할 수 없을 것이다.

물론 애초에 고사양 타깃으로 만들어진 게임이면 어쩔 수 없는 일이지만, 중저사양의 모델 역시 타깃으로 잡았고 메모리를 제외하면 분명 중저사양에서도 돌아갈 수 있는 게임임에도 불구하고 메모리 최적화 때문에 중저사양 모델에서 돌리지 못한다면 문제가 있다.

이런 메모리 최적화 문제에 대한 해결책은 여러가지가 있지만 그 중에서도 제일 먼저 살펴보아야할 부분이 UI다. 그럼 UI 텍스처 최적화를 통한 메모리 최적화에 대해서 알아보도록 하자.





유니티의 텍스처 압축 지원 받기


유니티에서는 텍스처 리소스에 대해서 기본적인 압축 기능을 자체적으로 제공한다. 이러한 압축을 지원받는 것 만으로도 압축되지 않은 리소스에 비해서 상당한 수준의 용량을 아낄 수 있게 된다.

유니티의 텍스처 압축은 모든 텍스처에 적용되는 것은 아니고 한 가지 제약사항이 존재한다.


그것은 바로 텍스처의 너비와 높이 둘 다 4의 배수가 되어야 한다는 것이다. 만약 너비나 높이 둘 중 하나라도 4의 배수가 되지 못하면, 해당 텍스처는 무압축 상태로 빌드된다.



위의 이미지를 보면 텍스처 압축을 지원받지 못한 900x359 크기의 텍스처는 1.2MB지만 900x360 크기의 텍스처는 RGBA Compressed DXT5 포맷으로 압축되어 316.4KB로 엄청나게 크기가 줄어든 것을 확인할 수 있다.


단, DXT5 포맷의 압축 방식은 iOS에서는 지원되지 않기 때문에, 다른 압축 포맷을 직접 지정하는것이 좋다.





스프라이트 패킹(Sprite Packing)


UI 텍스처 압축을 통해 용량을 아꼈다면 이번에는 메모리를 아껴볼 차례다.



유니티에서 이미지는 메모리에 올라갈 때, 정사각형의 형태나 각 변의 길이가 POT(2의 승수, 128 256 512 같은..)인 형태로 올라가게 되는데, 만약 이미지가 정사각형이 아니거나 각 변의 길이가 POT인 형태라면 이미지의 가로변과 세로변의 길이 중 긴 변의 길이에 맞춰서 정사각형의 크기의 메모리를 할당받기 때문에 낭비되는 메모리 공간이 많아진다. 이 문제는 한 쪽변이 다른 한 쪽변의 길이에 비해서 매우 길어질 수록 심해진다.



이러한 문제를 해결하기 위한 것이 바로 스프라이트 패킹이다. 스프라이트 패킹이란 여러개의 이미지를 같은 패키지로 패킹해서 메모리에 함께 올리는 것으로 모든 UI 텍스처를 따로 메모리에 올렸을 때보다 메모리의 낭비를 많이 줄일 수 있게 된다.


유니티에서 스프라이트 패킹 방법으로 레거시 스프라이트 패커(Legary Sprite Packer)와 스프라이트 아틀라스(Sprite Atlas) 두 가지를 제공한다.





슬라이스드 이미지 사용하기(Sliced Image)


사실 UI 리소스의 경우에는 특별한 이미지가 많이 사용된다기 보다는 사용되는 이미지가 반복되어서 사용되는 경우가 많다. UI를 묶어주는 패널(Pannel), 입력을 받는 인풋 필드(Input Field), 버튼(Button) 등이 여기에 속한다.


이런 것에 사용되는 리소스는 재사용성을 높여야 되지만, 초보 개발자나 초보 UI 디자이너는 예쁘거나 멋지게 만들어야 되는다는 집착에 빠지거나, 최적화에 대한 신경을 못쓰고 만들어서, 패널이나 버튼에 들어갈 이미지를 크기에 맞춰서 필요한 모든 사이즈 별로 만드는 경우가 종종 있다.



예를 들어 760x960 크기의 UI가 필요해서 거기에 해당하는 리소스를 만들어 냈다고 해보자. 이걸 게임에 그대로 적용해버리면 패널을 꾸미기에 따라서는 UI가 예뻐보일 수는 있을 것이다. 하지만 압축된 리소스임에도 불구하고 0.7MB라는 엄청난 용량을 자랑하는 것을 볼 수 있다. 이게 겨우 하나여서 0.7MB지, 여러 종류의 많은 UI를 띄워야 하는 게임이어서 해당 UI의 크기 별로 패널 리소스를 새로 만들어서 적용한다면 그리고 그 와중에 몇몇 리소스가 압축되지 않는 불상사가 발생한다면 게임의 용량이나 메모리 소모는 엄청난 수준이 될 것이다.


버튼이나 패널 같은 UI의 리소스의 경우에는 일반적으로 리소스의 모서리 부분을 제외한 중심 부분은 반복되는 경우가 많다. 슬라이스드 이미지란 바로 이 점에서 착안한 아이디어로 모서리 부분과 반복될 중심 부분 조금만 있으면 유니티 엔진이 중심 부분을 자동으로 채워주는 기능이다. 그렇기 때문에 패널 리소스 중에서도 모서리 부분과 반복될 중심 부분 약간 만으로 리소스를 만들면 위 이미지와 같은 커다란 패널 UI 리소스는 아래 이미지와 같이 아주 작게 줄일 수 있다.



불필요한 중심 부분을 제거하는 것만으로도 이미지의 크기와 용량이 700분의 1로 줄어들었다.




리소스의 중심 부분을 제거한 뒤에는 유니티의 스프라이트 에디터(Sprite Editor)에서 원형을 유지할 부분과 크기가 늘어났을 때 자동으로 채워질 부분을 설정해주면된다. 위의 그림처럼 설정하면 UI의 크기가 늘어났을 때 모서리 부분은 원형을 유지하고 가운데 십자 부분만 자동으로 채워지는데 씬에서 UI Image를 추가할 때, Image Type를 Sliced로 변경해주면 작은 이미지가 전혀 확대되거나 이상한 모양으로 늘어지지 않음을 확인할 수 있다.






오른쪽의 패널이 슬라이스드 이미지를 사용한 UI이고 오른쪽은 그냥 패널 이미지를 통째로 사용한 것이다. 둘이 차이가 없음을 확인할 수 있다. 하지만 패널 리소스에 그라데이션이나 디자인이 들어갔다면 그 퀄리티는 다를 수도 있다. 하지만 그 부분은 저사양에서는 단순한 패널만 보여주고 유저가 고사양을 선택한다면 패널 UI 위에 디자인 이미지를 올려서 보여줄 수도 있다.

반응형

+ Recent posts