Version: 2021.2
에셋 번들 빌드
에셋 번들의 전문적인 활용

에셋 번들 종속성

에셋 번들에 속한 UnityEngine.Objects 중 하나 이상이 다른 번들에 있는 UnityEngine.Object에 대한 레퍼런스를 가지고 있을 경우 해당 에셋 번들은 다른 에셋 번들에 종속합니다. 하지만, UnityEngine.Object에 에셋 번들이 포함되지 않은 UnityEngine.Object에 대한 레퍼런스가 포함되어 있으면 종속 관계는 형성되지 않습니다. 이 경우 번들이 종속하는 오브젝트가 에셋 번들이 빌드되는 번들로 복사됩니다. 만약 다수의 번들에 존재하는 다수의 오브젝트가 특정 번들에 할당되지 않은 동일한 오브젝트에 대한 레퍼런스가 포함된 경우, 해당 오브젝트에 종속 관계를 가지는 모든 번들은 해당 오브젝트를 각각 복사하여 빌드된 에셋 번들에 포함합니다.

에셋 번들이 종속성을 포함하는 경우, 인스턴스화하는 오브젝트가 로딩되기 이전에 종속성을 가지는 번들이 로딩되도록 해야 합니다. Unity 엔진은 종속성을 자동으로 로딩하지 않습니다.

예제를 하나 들어보겠습니다. 번들 1 에 있는 머티리얼이 번들 2 에 있는 텍스처를 참조한다고 가정하겠습니다.

이 경우 번들 1 의 머티리얼을 로딩하기 이전, 번들 2 를 메모리로 로딩해야 합니다. 번들 1번들 2 를 로딩하는 순서는 중요하지 않습니다. 다만, 번들 1 의 머티리얼이 로딩되기 이전에 번들 2 가 로딩되어야만 합니다. 다음 섹션에서는 이전 섹션에서 다룬 AssetBundleManifest 오브젝트를 활용하여 어떻게 런타임 시점에 종속성을 결정하고 로딩할 수 있는지 알아보겠습니다.

에셋 번들 간의 중복 정보

기본적으로 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 (moduleAB == null)
        {
            Debug.Log("Failed to load AssetBundle!");
            return;
        }
        var prefab = moduleAB.LoadAsset<GameObject>("example-prefab");
        Instantiate(prefab);
    }
}

올바르게 로드된 머티리얼이 있는 프리팹
올바르게 로드된 머티리얼이 있는 프리팹

참고: LZ4 압축 및 비압축 에셋 번들을 사용하는 경우 AssetBundle.LoadFromFile이 해당 콘텐츠의 카탈로그만 메모리에 로드하고 콘텐츠 자체는 로드하지 않습니다. 이 문제가 발생하는지 확인하려면 메모리 프로파일러 패키지를 사용하여 메모리 사용량을 검사하십시오.

에셋 번들 빌드
에셋 번들의 전문적인 활용