[Unity] 에셋번들 사이즈 줄이기
부제: Assetbundle dependecy를 개선하여 에셋번들 사이즈 줄이기
Unity로 게임 개발을 하다보면 리소스(프리팹, 텍스쳐, 애니매이션, 메터리얼 등)를 대부분 assetbundle로 분리하여 관리하게 된다. 특히, 개발 기간동안 리소스가 점점 많아지게 되면 assetbundle이 중복된 리소스를 포함하는 경우가 생기는데, 이를 정리하는 것은 쉽지 않은 일이다. 중복된 리소스는 어떻게 하면 생기게 되는지, 그리고 어떻게 개선할 수 있는지를 간단히 샘플로 테스트 해보았다. 테스트한 Unity 버젼은 2017.4.28f1 이다.
Asset Store ((Unity Editor) Window > Asset Store)를 열어서 Asset Bundle Browser를 설치하자. (무료다!) Assetbundle이 어떤 리소스들로 만들어 졌는지 내역을 확인 할 수 있고, 리소스들의 연관 관계(dependency)도 확인이 가능하다.
Asset Bundle Browser를 Import하면, Project 패널에서 아래와 같이 폴더가 생긴다. 이 에셋의 실행은 잠시 미뤄두고, 테스트를 위해 Cube 게임 오브젝트와 Sphere 게임 오브젝트를 하나씩 만들고 프리팹으로 생성 해보았다. Cube와 Sphere는 동일한 메터리얼( 파일명: 1.material )로 세팅하였다.
그럼 이제 Cube.prefab과 Sphere.prefab을 각각 Assetbundle이 되도록 세팅해보자.
간단히 세팅이 끝났다. 이제 처음에 설치한 Assetbundle Browser를 통해 Assetbundle이 어떻게 구성되어 있는지 확인해보자. (메뉴 Window > Assetbundle Browser 실행)
‘cube‘를 클릭 해보면, 어떤 Asset들이 포함되어 있는지 오른쪽 패널에 표시된다. Cube.prefab, 1.material, _001.png 파일이 포함되어 있다. 특이점은 Messages란에 경고 메세지가 표시되어 있는데, 리소스 중에서 일부가 다른 assetbundle에도 포함되어 있다는 것을 알려주고 있다. ‘sphere’도 클릭 해보면, 동일하다. 즉, ‘1.material‘이 두개의 assetbundle에 중복되어 포함되어 있다. 그럼 assetbundle을 빌드해서 결과물을 확인해보자. Assetbundle Browser에서 아래와 같이 빌드 가능하다.
빌드가 끝나면 아래와 같이 cube (126KB)와 sphere (126KB)가 Assetbundle로 생성된 것을 확인할 수 있다. (Total: 252 KB)
위의 그림에서와 같이 cube와 sphere가 각각 중복된 asset을 가지고 있기 때문에 사이즈를 줄이려면 중복 이슈를 해결할 필요가 있다.이 이슈에 대해서 Unity Blog에 잘 설명되어 있는데, 한번 읽어보는 것도 좋을 듯 하다. (Link)
1.material이 중복되는 이슈를 제거하기 위해서는, 1.material을 에셋번들로 분리하는 방법이 있다. 1.material을 분리하게 되면, cube와 sphere는 1.material을 assetbundle에 포함하지 않고, dependency 정보만들 가지고 있기 때문에 하나의 1.material만 메모리에 로딩하게 된다. 한번 테스트를 해보자.
아래와 같이 1.material을 mat_1로 지정하였다.
이제 다시 Assetbundle Browser를 통해 각 번들을 확인해보자.
Assetbundle Browser에서는 이전과는 다르게 Dependent On 항목에서 mat_1과 연관 관계가 있다고 표시되고, 오른쪽 패널에서는 1.material이 빠진 것을 볼 수 있다. 이 상태에서 다시 asetbundle 빌드를 해보자.
cube와 sphere의 사이즈가 2KB로 줄었고, mat_1만이 125KB가 되었다. (Total: 129KB)
정리하자면, 중복되어 생성된 번들 사이즈가 252KB였다면, 공통된 리소스를 번들로 분리한 후의 사이즈는 129KB가 된 것이다. Good!!!
여기서는 테스트 목적으로 material을 분리하였지만, 실제 프로젝트에서는 공통으로 쓰이는 atlas, textures, prefabs 등 모든 타입이 대상이 될 수 있을 것이다.
안녕하세요 블로그 잘 보았습니다. 질문이 하나 있습니다.
저렇게 머티리얼을 별도로 분리하게 되면, 머티리얼 연결을 어떻게 해 줘야 하는 건가요?
자동으로 안되는것 같아서요.
코드에서 머티리얼을 로딩하고 오브젝트에 연결을 해 줘야 하는건가요?
안녕하세요~ 위의 글은 유니티에서 제공하는 에셋번들 매니져(https://docs.unity3d.com/Manual/AssetBundles-Manager.html)를 사용한다는 가정에서 썼는데요. 그래서 dependency를 가진 에셋번들을 같이 로딩을 해주기 때문에 별도의 로딩 과정이 없습니다. 커스텀한 로딩 스크립트를 직접 작성하셨다면, 분리된 에셋번들을 로딩하는 과정을 추가해야 할 것 같습니다. 🙂