이 페이지에서는 에셋 번들에서 지원되는 압축 옵션과 빌트인 에셋 번들 캐싱 지원에 대한 영향을 설명합니다.
에셋 번들 파일은 짧은 헤더 데이터 구조와 해당 가상 파일이 포함된 콘텐츠 섹션으로 구성된 아카이브 포맷입니다. 헤더 섹션은 압축되지 않으며 콘텐츠 섹션은 선택적으로 압축할 수 있습니다. 기본적으로 Unity는 콘텐츠 섹션을 전체 파일 압축(LZMA)으로 압축하고 청크 기반 압축(LZ4)으로 에셋 번들을 캐시합니다.
LZMA
압축을 사용하면 에셋 번들 파일의 전체 콘텐츠 섹션이 단일 스트림으로 압축됩니다. 이 전체 콘텐츠 접근 방식은 청크 기반 압축보다 파일 크기가 더 작습니다. 이는 CDN(콘텐츠 전송 네트워크)에서 다운로드한 에셋 번들에 대해 선호되는 포맷입니다. 하지만 이러한 아카이브에서 에셋을 읽으려면 전체 파일의 압축을 RAM에 풀어야 한다는 단점이 있습니다. 이 방법은 에셋 번들에 에셋이 포함되어 있어 번들에서 하나의 에셋을 사용하면 모든 에셋이 로드되는 경우에 가장 적합합니다. 캐릭터나 씬에 대한 모든 에셋을 패키징하는 것이 이 방법을 사용할 수 있는 번들의 몇 가지 예시입니다. 이는 특정 압축을 지정하지 않고 BuildPipeline.BuildAssetBundles
를 호출할 때 사용되는 포맷입니다(예: BuildAssetBundleOptions.None
).
에셋 번들은 데이터가 완전히 압축되지 않은 방식으로 빌드할 수도 있습니다. 이처럼 압축되지 않은 방식의 단점은 일부 유형의 콘텐츠는 에셋 번들 내에서 압축될 가능성이 높을 수 있기 때문에 파일 다운로드 크기가 커진다는 것입니다. 하지만 압축을 풀 필요가 없으므로 다운로드 후 로드 시간이 훨씬 빨라질 수 있습니다. 이는 특히 큰 에셋 번들에서 몇 개의 오브젝트만 로드할 때 유용합니다. 압축되지 않은 에셋 번들은 16바이트로 정렬됩니다. 이 포맷은 BuildPipeline.BuildAssetBundles를 호출할 때 BuildAssetBundleOptions.UncompressedAssetBundle
플래그를 지정하여 사용할 수 있습니다.
LZ4
는 에셋 번들을 조각 또는 “청크” 단위로 압축 해제할 수 있는 청크 기반 알고리즘을 사용합니다. 에셋 번들을 작성하는 동안 콘텐츠의 각 128KB 청크는 저장 전에 압축됩니다. 각 청크가 개별적으로 압축되기 때문에 전체 파일 크기는 LZMA로 압축된 에셋 번들보다 큽니다. 하지만 이 방식을 사용하면 전체 에셋 번들의 압축을 풀지 않고 요청된 오브젝트에 필요한 청크만 선택적으로 검색하여 가져오고 로드할 수 있습니다. LZ4를 사용하면 압축되지 않은 번들과 비슷한 로드 속도를 가지게 되지만 디스크의 용량은 적게 차지합니다. 아래에서 설명하는 대로 이 포맷은 에셋 번들 캐시에서 선호하는 형식이며, 설치의 일부로 배포하는 에셋 번들이나 크기가 중요하지 않은 다른 경우에도 좋은 선택이 될 수 있습니다. 이 포맷은 BuildPipeline.BuildAssetBundles를 호출할 때 BuildAssetBundleOptions.ChunkBasedCompression
플래그를 지정하여 사용할 수 있습니다.
데이터마다 압축되는 크기가 다르기 때문에, 지원되는 각 옵션으로 프로젝트를 다시 빌드하고 실제 크기 차이를 측정하여 실험해 보는 것이 좋습니다. 결과를 참조하여 어떤 포맷을 사용할지 결정할 수 있습니다.
커스텀 캐싱 솔루션으로 데이터를 다운로드 및 저장하는 경우 AssetBundle.RecompressAssetBundleAsync를 사용하여 압축을 변경할 수 있습니다. 예를 들어 LZMA 포맷 에셋 번들을 다운로드 후 LZ4 포맷이나 압축되지 않은 포맷으로 전환할 수 있습니다.
참고:WebGL은 에셋 번들에 LZMA 압축을 지원하지 않습니다.WebGL 플랫폼에서 에셋 번들에 LZ4 압축을 사용하십시오.자세한 내용은 에셋 번들로 로드 시간 단축을 참조하십시오.
웹 서비스를 통해 에셋 번들을 다운로드할 때는 플레이어가 실행될 때마다 기기가 동일한 콘텐츠를 다운로드할 필요가 없도록 캐싱을 고려해야 합니다. 에셋 번들은 다시 빌드될 수 있으므로, 로컬로 캐시된 에셋 번들을 최신 버전으로 교체할 수 있는 메커니즘을 갖추는 것도 중요합니다.
Unity는 UnityWebRequestAssetBundle을 통해 다운로드한 에셋 번들을 저장할 수 있는 빌트인 디스크 기반 캐시를 제공합니다. 캐싱을 활성화하려면 UnityWebRequestAssetBundle.GetAssetBundle
을 호출할 때 버전 정수 또는 버전 해시 파라미터를 지정해야 합니다. 기본적으로 디스크 캐시에 추가된 모든 에셋 번들은 LZ4 압축으로 전환됩니다. 따라서 재압축이 발생하기 때문에 처음에 LZMA 에셋 번들을 다운로드하고 로드하는 데 시간이 오래 걸리지만, 이후 로드에서는 캐시된 버전을 사용하여 빠르게 실행됩니다. Caching.compressionEnabled가 false인 경우 Unity는 에셋 번들을 압축되지 않은 포맷으로 디스크 캐시에 씁니다.
인터넷을 통해 에셋 번들을 다운로드할 때는 손상되거나 조작된 파일 콘텐츠가 캐시에 사용되지 않도록 조치를 취해야 합니다. Unity가 파일을 캐시에 추가하는 동안 다운로드한 콘텐츠와 값을 비교할 수 있도록 UnityWebRequestAssetBundle.GetAssetBundle
을 호출할 때 예상 CRC를 지정해야 합니다. CRC 검사는 LZMA 에셋 번들을 LZ4로 전환하는 동안 낮은 비용으로 수행할 수 있습니다. 확인된 파일이 캐시에 도달하면 CRC 검사를 다시 반복하지 않아도 됩니다. 에셋 번들 다운로드 무결성 및 보안도 참조하십시오.
Caching 클래스는 빌트인 에셋 번들 캐시를 관리하는 데 사용할 수 있습니다. 예를 들어 콘텐츠를 지우거나 에셋 번들이 이미 캐시되어 있는지 확인할 수 있습니다.
Unity는 성능 향상을 위해 청크 기반 또는 압축되지 않은 에셋 번들을 로드하는 동안 압축되지 않은 일부 데이터를 메모리에 보관합니다. 하지만 이 캐싱의 경우 기본 에셋 번들 파일의 크기에 관계없이 크기가 고정되어 있습니다.
에셋 번들을 로드하려면 Unity는 디스크의 파일, 메모리의 파일 또는 C# FileStream을 통해 해당 콘텐츠에 무작위로 액세스해야 합니다. 또한 에셋 번들이 압축되지 않은 상태이거나 청크 기반 압축(LZ4)을 사용해야 합니다. 로드 가능한 에셋 번들을 설정하기 위해 Unity는 메모리 내 임시 에셋 번들을 생성해야 할 수도 있습니다. 에셋 번들 콘텐츠는 메모리에 보관되면 빠르게 로드될 수 있으므로 이러한 상황이 항상 나쁜 것은 아닙니다. 하지만 RAM 사용량을 최소화하고 실시간 압축 전환으로 인해 로드 시간이 길어지지 않도록, 대부분의 경우 파일을 디스크에 로컬 에셋 번들 또는 캐시된 다운로드로 표시하는 것이 좋습니다.
메모리 내 임시 에셋 번들은 다음과 같은 경우에 생성됩니다.
임시 파일에 사용된 메모리는 모든 읽기가 완료되고 AssetBundle.Unload가 호출되면 해제됩니다.
참고: 디스크 기반 에셋 번들 캐싱을 지원하는 플랫폼에서는 Caching.compressionEnabled 설정이 메모리 내 임시 에셋 번들에 사용되는 포맷에 영향을 미칩니다. 기본적으로 이 설정은 true이며 메모리 내 에셋 번들은 LZ4를 사용합니다. Caching.compressionEnabled가 false인 경우 이러한 메모리 내 파일은 압축되지 않으며, 따라서 RAM을 훨씬 더 많이 차지할 수 있습니다. 캐싱을 지원하지 않는 플랫폼에서는 메모리 내 포맷이 항상 LZ4입니다. 입력이 다른 포맷인 경우 실시간으로 전환이 수행되므로 로드 시간이 늘어날 수 있습니다.
참고: 청크 기반 파일에 대해 AssetBundle.LoadFromFile, AssetBundle.LoadFromFileAsync, AssetBundle.LoadFromStream 또는 AssetBundle.LoadFromStreamAsync를 호출할 때 CRC 검사를 수행하면 파일의 각 청크를 모두 읽고 압축을 해제하게 됩니다. 이 계산은 전체 파일을 RAM에 로드하는 것이 아니라 청크별로 이루어지므로, 메모리 문제는 없지만 로드 시간이 늘어날 수 있습니다. LZMA 포맷의 에셋 번들을 로드할 때는 항상 모든 콘텐츠의 읽기 및 압축 풀기가 수행되므로 CRC 검사를 수행하는 데 큰 추가 비용이 들지 않습니다.
Memory Profiler 패키지와 같은 메모리 프로파일러 툴은 로드된 에셋 번들이 얼마나 많은 메모리를 사용하는지 확인하는 데 유용할 수 있습니다.