본문 바로가기

TOOL/Unity

Asset Bundle

Resorce Folder 사용을 자제할것


Resorce Folder는 앱에 같이 묶여 들어가기 때문에 사용 유무에 상관없이 packaging되어 apk의 크기가 커지고

그렇게 되면 app이 시작할때 resource file을 read하는 작업도 느려진다.

또한 resource folder를 사용할 때 current scene에서 사용되지 않는 object라도 meta data를 전부 memory에 띄우기 때문에 asset이 많을수록

기본적인 memory사용량이 계속 증가한다.


하지만 app에서 처음부터 끝까지 반드시 사용될경우 Resorce Folder에 넣어도 무관



Asset : Unity로 게임을 만들때 사용되는 Image, text, audio, animation data등을 의미


Asset Bundle : 여러 에셋들을 하나로 묶어주는 File format

(초기 인스톨 용량을 줄이거나 Runtime Memory를 줄이는 용도로 사용되나 잘못사용하면 memory problem이 발생하기 쉽다.)

Asset Bundle은 다양한 파일과 Manifest file로 구성되며, 사용될 때 직렬화(Serialization), 역직렬화(Deserialization)과정을 거치게된다.



직렬화(Serialization)과정


Object의 data를 순서대로 나열하는 과정

기본적인 file의 read and write과정, Inspector title, Script reloading, Prefab, Instancing, Resource Folder도 Serialization과정을 거친다.



역직렬화(Deserialization)과정


Serialization 과정의 역순이며 순서대로 나열된 data는 다른파일, data base, menory를 거쳐 다시 data 조립과정을 거쳐 object가 된다



Asset bundle 구조


Header : Asset bundle의 식별 id와 component file, index에 해당되는 lookup table로 구성됨

Data segment : 여러 Asset정보가 담겨져 있다.


P.S) Lookup Table : AssetBundle 내 Asset들의 위치정보가 담겨져있는 이진균형탐색트리기반의 테이블


Asset bundle의 수가 너무 적을경우


memory 사용량 증가

loading time 증가

대용량 download



Asset bundle의 수가 너무 많을경우


build time 증가

개발과정 복잡

download time 증가



Asset bundle의 압축방식


1) LZMA(Non 선택시 사용방식) : Asset을 통째로 압축하는 방식

   압축효율은 높음, 1에셋 1번들상황적합, 무선네트워크 환경이 좋지않은 중국, 동남아에서 사용하기 적합하다.


2) Chunk base, LZ4 : Asset을 chuck로 나누어 효율적으로 압축하는 방식, 에셋이 chuck보다 크면 여러 chuck으로 저장해 효율적이다.

   압축효율은 LZMA보다 낮으나 빠르게 압축을 해제할 수 있음, 대부분 이 방식을 사용한다.


P.S) 압축이 언제나 유용한것은 아니다. 비압축시 로딩시간, build가 더 빠르며 Memory 사용량또한 비압축이 더 적은 memory를 사용한다.

또한 WebGL의 경우 압축 asset bundle을 사용하지 않는것을 권장한다.



Asset bundle 분류방법


1)논리적 개체별 분류법

기능적인 부분 개념으로 asset들을 분류하는 방법


2)타입별 분류법

비슷한 resource들끼리 bundle에 묶는 방식, 엔진 업데이트에 영향을 받지 않는 resource여야 되며

Shader는 platform별 호환성이 다르기 때문에 이 방법을 사용하면 안된다.


3)동시에 사용되는 콘텐츠별로 그룹화

하나의 scene, 한판에 같이 사용되는 것들을 그룹화



Asset bundle 사용방법


1)WWW.LoadFromCacheOrDownload 사용하는 방법 (해당방법은 2018이후 지원중단 예정이다.)


Asset bundle을 download 후 caching하고 그대로 저장하는 방식, 압축된 번들을 풀어서 caching하기에 사용하기 편하다.

다운로드 받는 중 파일을 통째로 memory에 올려놔 memory problem 발생할 수 있음

(Asset bundle을 각각 최대 10메가로 나누어 사용하길 권장, 그렇지않을경우 mobile에서는 memory가 터질 수도 있음)


2)UnityWebRequest 사용방법

위에서 언급했던 memory problem을 해결할 수 있는 방법


P.S) 

DownloadHandler : 에셋번들을 캐싱하고 해당 에셋번들과 기기에 있는 파일 정보를 대조해 버전이 구버전이면 업데이트를

진행하고 같을 경우 생략하는방식



Asset bundle 삭제요령


Scene A에서 Scene C로 넘어갈 때 A에서 사용했던 Asset bundle을 삭제하고 C에서 사용할 Asset bundle을 로드할 땐 보통

Scene C를 로드 후에 Scene A의 Asset bundle을 삭제한다.


하지만 이렇게 하게되면 A 에셋번들과 C에셋번들이 동시에 메모리에 적재됨

Memory = Scene A Asset bundle + Scene C Asset bundle => Memory 이슈발생


이를 해결하기위해 보통 Scene A와 Scene C 사이에 용량이 적은 Scene B를 임의로 넣는 방법을 사용한다.

이러한 Scene C는 보통 Loading Scene, 게임결과 Scene용도로 사용된다.



Asset bundle 메모리릭 이슈


Asset bundle 수행과정

File에서 Bundle을 load -> 불러온 bundle 에서 asset을 찾음 -> Asset instance화


불러온 bundle은 profiler의 Other - SerializedFile에 구분되고 instance화 된 asset은 asset category로 들어간다.

bundle의 asset을 직접 사용할 수 없으니 memory는 풀빌드에 비해 2배가 된다.


instance를 소멸하고 bundle도 해제를 시켜야 GC에 수집이 된다.



AssetBundle.Unload(bool unloadAllLoadedObjects)


번들 내의 모든 에셋을 언로드한다.

언로드 함으로서 에셋 번들에 있는 오브젝트에 대한 메모리를 전부 해제한다.


unloadAllLoadedObjects = false

Asset bundle 안에 있는 압축된 asset file data는 unload 되지만, 이 asset bundle에 의해 load된 실제 object는 그대로 유지된다.

당연히 이 asset bundle에서 추가적으로 object를 load할 수 없게된다.


unloadAllLoadedObjects = true

이미 load된 object도 포함하여 파괴된다. Scene에서 이러한 asset을 참조하는 object에 대해 그들에 대한 참조는 Missing이 됩니다.






참조

https://180bpm.tistory.com/138

http://www.inven.co.kr/webzine/news/?news=176811

http://www.inven.co.kr/webzine/news/?news=198839


AssetBundle.Unload( )관련 참조

https://ronniej.sfuh.tk/assetbundleusagepattern1/

'TOOL > Unity' 카테고리의 다른 글

Mono / Mono Behaviour  (0) 2019.03.05
IL2CPP / GCC / C# C++ Assembly 변환과정  (0) 2019.03.05
Asset Bundle Manager  (0) 2019.02.27
Asset bundle 사용법  (0) 2019.02.27
대표적인 Memory leak 발생 유형  (0) 2019.02.26