에셋 번들에 속한 UnityEngine.Objects
중 하나 이상이 다른 번들에 있는 UnityEngine.Object
에 대한 레퍼런스를 가지고 있을 경우 해당 에셋 번들은 다른 에셋 번들에 종속합니다. 하지만, UnityEngine.Object
에 에셋 번들이 포함되지 않은 UnityEngine.Object
에 대한 레퍼런스가 포함되어 있으면 종속 관계는 형성되지 않습니다. 이 경우 번들이 종속하는 오브젝트가 에셋 번들이 빌드되는 번들로 복사됩니다. 만약 다수의 번들에 존재하는 다수의 오브젝트가 특정 번들에 할당되지 않은 동일한 오브젝트에 대한 레퍼런스가 포함된 경우, 해당 오브젝트에 종속 관계를 가지는 모든 번들은 해당 오브젝트를 각각 복사하여 빌드된 에셋 번들에 포함합니다.
에셋 번들이 종속성을 포함하는 경우, 인스턴스화하는 오브젝트가 로딩되기 이전에 종속성을 가지는 번들이 로딩되도록 해야 합니다. Unity 엔진은 종속성을 자동으로 로딩하지 않습니다.
예제를 하나 들어보겠습니다. 번들 1 에 있는 머티리얼이 번들 2 에 있는 텍스처를 참조한다고 가정하겠습니다.
In this example, before loading the Material from Bundle 1, you would need to load Bundle 2 into memory. It does not matter which order you load Bundle 1 and Bundle 2, the important takeaway is that Bundle 2 is loaded before loading the Material from Bundle 1. In the section Using AssetBundles Natively we’ll discuss how you can use the AssetBundleManifest
object that is produced by the build to determine, and load, dependencies at runtime.
기본적으로 Unity는 에셋 번들 간의 중복 정보를 최적화하지 않습니다. 즉 프로젝트의 여러 에셋 번들에 동일한 정보(예: 여러 프리팹에서 사용되는 머티리얼)가 포함될 수 있음을 의미합니다. 여러 에셋 번들에서 사용되는 에셋을 공통 에셋이라고 합니다. 공통 에셋은 메모리 리소스와 로딩 시간에 영향을 미칠 수 있습니다.
이 페이지에서는 Unity가 에셋 번들 간의 중복 정보를 관리하는 방법과 최적화를 적용하는 방법에 대해 설명합니다.
기본적으로 Unity는 중복 정보를 저장하는 데 필요한 메모리를 줄이거나 최소화하기 위해 최적화를 수행하지 않습니다. 빌드 생성 중에 Unity는 에셋 번들 내에서 암시적으로 참조된 에셋의 복제본을 빌드합니다. 이러한 중복을 방지하려면 머티리얼 등과 같은 공통 에셋을 자체 에셋 번들에 할당하십시오.
예를 들어 자체 에셋 번들에 할당된 두 개의 프리팹이 있는 애플리케이션이 있을 수 있습니다. 이 두 프리팹은 모두 에셋 번들에 할당되지 않은 동일한 머티리얼을 공유합니다. 이 머티리얼은 에셋 번들에 할당되지 않은 텍스처를 참조합니다.
에셋 번들 워크플로를 따르고 CreateAssetBundles
예제 클래스를 사용하여 에셋 번들을 빌드하면 생성된 각 에셋 번들에 머티리얼(해당 셰이더, 참조된 텍스처 포함)이 포함됩니다. 아래 예제 이미지에서 프리팹 파일의 크기는 각각 383KB와 377KB입니다.
프로젝트에 더 많은 프리팹이 포함될 경우 이 동작은 설치 프로그램의 최종 크기, 그리고 두 에셋 번들이 로드될 때 런타임 메모리 공간에 영향을 줍니다. Unity는 동일한 머티리얼의 각 복사본을 고유한 머티리얼로 간주하기 때문에 에셋 번들 간의 데이터 중복도 배칭에 영향을 미칩니다.
데이터 중복을 방지하려면 머티리얼과 참조된 에셋을 자체 modulesmaterials
에셋 번들에 할당하십시오. 텍스처 종속성도 빌드 프로세스 중에 자동으로 에셋 번들에 포함되므로, 머티리얼에만 태그를 지정할 수도 있습니다.
이제 에셋 번들을 다시 빌드하면 생성된 결과물에 별도의 modulesmaterials
에셋 번들(359KB)이 포함됩니다. 이 에셋 번들에는 머티리얼, 연결된 텍스처가 들어 있습니다. 이를 통해 프리팹에 대한 다른 에셋 번들의 크기를 크게 줄일 수 있습니다(이전의 약 380KB에서 약 20KB로 크게 축소).
아래 이미지에서 이와 관련된 내용을 확인할 수 있습니다.
공통 에셋을 단일 에셋 번들로 추출하는 경우 종속성에 주의하십시오. 특히 프리팹을 사용하여 모듈을 인스턴스화하면 머티리얼이 로드되지 않습니다.
이 문제를 해결하려면 모듈에 속한 에셋 번들을 로드하기 전에 머티리얼 에셋 번들을 메모리에 로드하십시오. 이는 다음 예제의 materialsAB
변수에서 발생합니다.
using System.IO;
using UnityEngine;
public class InstantiateAssetBundles : MonoBehaviour
{
void Start()
{
var materialsAB = AssetBundle.LoadFromFile(Path.Combine(Application.dataPath, Path.Combine("AssetBundles", "modulesmaterials")));
var moduleAB = AssetBundle.LoadFromFile(Path.Combine(Application.dataPath, Path.Combine("AssetBundles", "example-prefab")));
if (materialsAB == null || moduleAB == null)
{
Debug.Log("Failed to load AssetBundle!");
return;
}
var prefab = moduleAB.LoadAsset<GameObject>("example-prefab");
Instantiate(prefab);
}
}
참고: LZ4 압축 및 비압축 에셋 번들을 사용하는 경우 AssetBundle.LoadFromFile이 해당 콘텐츠의 카탈로그만 메모리에 로드하고 콘텐츠 자체는 로드하지 않습니다. 이 문제가 발생하는지 확인하려면 메모리 프로파일러 패키지를 사용하여 메모리 사용량을 검사하십시오.