유니티/공통

유니티 - 에셋 번들에 대해 알아보자

근본넘치는개발자 2024. 10. 22. 23:51

오늘은 유니티에서 Resource 폴더 활용 글 작성 때 언급했던 것처럼

에셋 번들에 대해 찾아봤고, 정리하는 시간을 가질까 합니다.

 

2024.10.18 - [유니티/공통] - 유니티 - Resources를 활용해 에셋을 로드해보자

 

 

에셋 번들

여기서 말하는 에셋은 디스크의 실제 파일 / 아카이브 파일들을 말합니다.

 

간단히 말하면 유니티에서 Assets 폴더 아래 있는 모든 내용이

이에 해당하는 내용이라 할 수 있겠네요. 

 

이런 에셋들을 하나로 묶어서 관리하는 기법입니다.

동작 원리 / 사용 방법

 

우측 하단을 보면 AssetBundle이라는 메뉴가 있습니다.

 

우클릭을 통해 New를 만들 수 있습니다.

 

 

A라는 폴더를 누른 채로 AssetBundle을 만들었습니다.

 

이름은 Test로 지정해 주었습니다만

에셋번들의 이름은 항상 소문자로 된다고 합니다.

그래서 자동으로 test가 되었습니다.

 

 

 

에셋 번들을 만들었으니 스크립트 코드를 사용해서 익스포트 할 겁니다.

그 전에 아래와 같은 코드를 작성하고 메뉴를 추가해 줬습니다.

 

보시면 좌측 상단에 코드 내용에서

작성한 이름처럼 TestBundle 메뉴가 생긴 걸 보실 수 있습니다. 

 

참고로 코드는 유니티 공식 문서에서 가져와 실습했습니다.

 

관심 있으신 분은 하단에 링크를 걸어놓았으니

직접 들어가셔서 따라 해보시면 좋을 것 같습니다.

 

 

 

 

 

 

에셋 번들 빌드 방법에는 두 가지가 있다고 합니다.

 

하나는 빌트인 네이티브 API

(예: BuildPipeline.BuildAssetBundles, 

AssetBundle  UnityWebRequestAssetBundle)

 

다른 하나는 Addressable 패키지를 사용하는 방법입니다.

 

오늘은 일단 네이티브 API를 사용하는 모습을 보여드리겠습니다. 

 

BuildPipeline.BuildAssetBundles() 내용을 보시면

3가지가 들어가는 걸 확인 하실 수 있습니다.

 

들어가는 내용은 경로, 압축 설정 방식, 타겟 플랫폼입니다. 

 

에셋 번들을 압축하는 방식은 3가지로 구분됩니다.

LZMA, LZ4, 그리고 압축하지 않는 방식이라고 할까요? 

LZMA

에셋 번들 파일의 전체 콘텐츠 섹션이 단일 스트림으로 압축합니다.

(CDN(콘텐츠 전송 네트워크)에서 다운로드한 에셋 번들에 대해 선호되는 포맷 )

 

LZ4

에셋 번들을 조각 또는 “청크” 단위로 압축 해제한다고 합니다.

 

기본적으로 Unity는 콘텐츠 섹션을 전체 파일 압축(LZMA)으로 압축하고

청크 기반 압축(LZ4)으로 에셋 번들을 캐시한다고 합니다.

 

데이터가 완전히 압축되지 않은 방식

데이터가 완전히 압축되지 않은 방식은

파일 다운로드 크기가 커지기는 하지만 압축을 풀 필요가 없으므로

다운로드 후 로드 시간이 훨씬 빨라질 수 있기에

주로 큰 에셋 번들에서 몇 개의 오브젝트만 로드할 때 사용되는 듯합니다. 

 

 

작성한 코드를 실행시켜 보겠습니다.

추가한 메뉴를 눌러 보면 코드 내용에 따라

 

 

AssetBuldes 폴더가 추가 되었고,

폴더 내부를 보시면 아까 만들었던 test가

AssetBundle안에 압축되어 들어간 걸 확인할 수 있었습니다.

 

이제 압축한 에셋 번들에서 반대로 로드를 통해

데이터를 가져와 사용할 수 있게 되었습니다. 

 

로드하는 방식은 버전에 따라서 내용이 다른 건지

예전 자료들에서는 4개를, 2023.2 버전(제가 찾은 가장 최신 버전)에서는 2개를 소개하더군요.

 

일단 2가지는 

 

AssetBundle.LoadFromFile

 UnityWebRequestAssetBundle.GetAssetBundle 이고,

AssetBundle.LoadFromFile로 로드하는 걸 보여드리겠습니다.

 

AssetBundle.LoadFromFile

 

AssetBundle.LoadFromFile은  디스크에서 직접 파일 콘텐츠를 점진적으로 읽을 수 있기 때문에

로컬 스토리지에서 비압축 및 청크 압축 번들(LZ4)을 로드할 때 매우 효율적이라고 합니다.

이 방법을 사용하여 전체 파일 압축(LZMA)으로 압축된 파일을 로드하면

먼저 파일을 메모리로 완전히 압축 해제해야 하므로 효율성이 떨어진다고 합니다.

 

아래와 같이 코드를 작성 후 실행해 봤습니다.

LoadFromFile의 경로는 "이전에 번들을 만들 때 적었던 경로/번들의 이름"(이전에 만들었던 test)을 넣어주었고,

AssetBundle test안에 있는 내용에서 Snow라는 GameObject를 불러와 생성해봤습니다.

 

 

 

주의 할 점

 

filter Selected Name을 통해 어떤 에셋이 test로 묶여있는지 확인할 수 있습니다.

다만 압축 파일을 언제 만들었냐에 따라 압축 파일 내에는 없을 수 있으므로

실행하기 전에 다시 한번 압축 파일을 만드는 걸 추천합니다.

- 이 점 때문에 예제 따라 하다가 한참 찾았네요;;;

 

Unity에서는 오브젝트가 액티브 씬에서 제거될 경우 자동으로 언로드되지 않기에 

사용하지 않게 되는 경우 수동으로 할당을 해제해야 합니다.  

 

방법은 간단합니다.

AssetBundle.Unload(true)나

 AssetBundle.UnloadAsync(bool)을 사용하면 됩니다. 

 

Unload는 메모리에서 에셋 번들 헤더와 기타 데이터 구조를 제거하여 에셋 번들을 언로드하는 비정적 함수로서

AssetBundle.Unload(false)를 사용하면 중복된 오브젝트 및 기타 문제가 발생할 수 있다고 합니다.

대부분의 프로젝트에서 이러한 문제를 방지하려면 AssetBundle.Unload(true)를 사용해야 합니다

 

현재는 설명을 위해 조건이 없지만 상황에 맞게 조건을 걸어서 직접 해제해야 한다.

 

 

의존성 문제

ex) : cube 프리팹을 AssetBundle로 만드는 경우 Cube라는 Mesh를 의존하고 있습니다. 

 

이를 해소하기 위해 코드 복잡도가 증가할 수 있는 문제가 있고,

 

Bundle1과 Bundle2에 들어있는 오브젝트에서 같은 Mesh를 사용하지만

어떻게 묶냐에 따라서 Mesh가 추가 복제되어

메모리 문제가 발생하거나 의존성에 따른 문제가 발생할 가능성이 생깁니다.

 

그럼, 번들을 어떻게 묶어야 할까 

여러 가지가 있지만 일단은 크게 3가지로 구분하는 듯합니다.

 

논리적 객체 그룹화 

= 기능을 기준으로 결정

 

타입 그룹화

= 비슷한 타입끼리 묶음

 

동시 콘텐츠 그룹화

= 동시에 로드되고 사용될 에셋들을 하나로 묶는 개념

 

 

사실 이런 방식들보다 가장 중요한 건 필요한 부분만 로드하고 

중복적으로 메모리에 상주하지 않도록 하는 관리가 필요하다고 합니다.

마무리 

오늘은 일단 간단하게 에셋번들에 대해 맛만 봤습니다.

정리만 해도 어렵네요;; 

 

에셋번들에서 더 발전시킨 부분이 "어드레서블"이라고 한다고 합니다.

다음 시간엔 어드레서블에 대해서도 정리하여

한번 글을 작성해 보도록 하겠습니다.

 

 

참고한(혹은 참고하면 좋을) 자료

https://youtu.be/mC2d94bfI2w?si=YaBsPq0OWL8xxgZG

https://unity.com/kr/blog/engine-platform/unity-asset-bundles-tips-pitfalls

 

Unity 에셋 번들 팁 및 위험 요소

게임 성능, 메모리 런타임 사용량, 전반적인 호환성을 중점적으로 에셋 번들의 잘 알려지지 않은 측면에 대해 알아보세요.

unity.com

https://docs.unity3d.com/kr/530/Manual/BuildingAssetBundles.html

 

에셋 번들 빌드(Building AssetBundles) - Unity 매뉴얼

에셋 번들(Unity 에디터와 스크립트에서 AssetBundle__로 불림)을 만들기 위해서는 먼저 프로젝트 폴더에서 번들에 포함할 에셋을 선택해야 합니다. 그 에셋을 위한 인스펙터 창의 맨 아래쪽에 AssetBun

docs.unity3d.com

https://youtu.be/Z9LrkQUDzJw?si=ki08gQwCJSlfv_30

https://docs.unity3d.com/kr/2023.2/Manual/AssetBundlesIntro.html

 

에셋 번들 - Unity 매뉴얼

에셋 번들 은 플랫폼별 비코드 에셋(예: 모델, 텍스처, 프리팹, 오디오 클립, 씬 전체)이 들어 있는 아카이브 파일이며 런타임 시점에 로드할 수 있습니다. 에셋 번들에는 서로 종속성을 표시할

docs.unity3d.com

https://learn.unity.com/tutorial/assets-resources-and-assetbundles#Managing_Loaded_Assets

 

Assets, Resources and AssetBundles - Unity Learn

This is a series of articles that provides an in-depth discussion of Assets and resource management in the Unity engine. It seeks to provide expert developers with deep, source-level knowledge of Unity's Asset and serialization systems. PLEASE NOTE: this t

learn.unity.com