다음 메서드는 에셋 번들 빌드가 실행된 후 정보를 수집하는 데 유용할 수 있습니다. 예기치 않은 동작을 조사하거나 번들에 대한 에셋 할당을 조정할 때도 유용할 수 있습니다.
Unity 에디터 로그는 빌드 중에 경고 또는 오류 메시지와 같은 정보를 수집합니다. 또한 에셋 번들 빌드가 끝나면 각 에셋 번들의 유형 및 크기에 대한 요약 정보를 보여 주는 자세한 메시지가 기록됩니다.
에셋 번들 빌드는 프로젝트 디렉토리 내 Library/LastBuild.buildreport
에 작성되는 Unity SerializedFile인 BuildReport를 생성합니다. 이 파일은 빌드 단계의 타이밍 요약과 에셋 번들 콘텐츠의 세부 정보를 확인하는 데 유용합니다. BuildReport API를 사용하면 BuildReport 파일에서 정보를 읽을 수 있습니다.
지원되지 않는 두 가지 툴을 사용하여 BuildReport의 콘텐츠를 볼 수 있습니다.
각 에셋 번들과 함께 생성되는 매니페스트 파일은 에셋 번들의 콘텐츠에 대해 실제로 읽을 수 있는 일부 세부 정보를 제공합니다.
Unity는 반복 작업 시간을 단축하기 위해 에셋 번들에 대한 증분 빌드를 지원합니다. 예를 들어 이전 빌드의 요소를 마지막 빌드 이후 변경되지 않은 프로젝트에 다시 사용할 수 있습니다. 이렇게 하면 반복 시간을 단축할 수 있지만, 특히 빌드 콜백으로 실행되는 스크립트가 비결정론적 방식으로 데이터를 변경하는 경우 입력의 변경 사항을 감지하는 기능에 몇 가지 제한이 발생합니다. 따라서 에셋 번들의 공식 릴리스를 빌드할 때는 항상 증분 빌드가 아닌 클린 빌드를 수행해야 합니다.
BuildPipeline.BuildAssetBundles()에 옵션으로 전달되는 BuildAssetBundleOptions.ForceRebuildAssetBundle
플래그는 클린 빌드를 수행하는 데 권장되는 방법입니다.
드문 경우지만 Library/ShaderCache 디렉토리를 지우는 것도 바람직할 수 있습니다. 이 캐시는 BuildAssetBundleOptions.ForceRebuildAssetBundle이 지정되면 플러시되지 않습니다. 많은 프로젝트에서 셰이더 컴파일 단계는 시간이 많이 걸리므로, 캐시를 지우면 다음 플레이어 또는 에셋 번들 빌드에 많은 시간이 추가될 수 있습니다.
또는 완전한 클린 빌드를 수행하는 가장 안정적인 방법은 Unity를 중지하고 프로젝트의 Library 디렉토리를 지운 다음 Unity를 재시작하는 것입니다. 이 방법은 모든 프로젝트 에셋을 다시 임포트하고 다른 데이터를 다시 생성해야 하므로 시간이 많이 소요될 수 있습니다.
에셋 번들 내부를 직접 살펴보거나 두 에셋 번들의 콘텐츠를 비교해야 하는 경우가 있습니다.
Unity 에디터 설치 시 WebExtract
및 Binary2Text
실행 파일이 포함되어 있습니다. WebExtract를 사용하면 압축 파일 추출과 유사하게 에셋 번들 안에 중첩된 파일을 추출할 수 있습니다. 그런 다음 Binary2Text를 사용하여 바이너리 SerializedFile의 콘텐츠를 텍스트 포맷의 덤프로 생성할 수 있습니다. 이 출력은 Unity에서 사용하는 yaml 포맷과 어느 정도 유사합니다.
에셋 번들 SerializedFile의 콘텐츠를 텍스트 형식으로 확인하는 또 다른 유사 메커니즘은 UnityDataTools
를 “dump” 인자와 함께 실행하는 것입니다.
직렬화된 파일의 원시 콘텐츠는 특히 셰이더나 메시 또는 바이너리 데이터가 있는 경우 매우 기술적이고 용량도 큰 경향이 있습니다. 그러나 이러한 덤프는 문제를 파일 내의 특정 오브젝트로 좁힐 수 있다면 풍부한 정보를 제공할 수도 있습니다. 비교 툴을 사용하여 두 개의 유사한 에셋 번들에서 추출된 콘텐츠를 비교하면 정확한 차이점을 손쉽게 식별할 수 있습니다.
BuildPipeline.BuildAssetBundles API의 인자를 통해 에셋 번들을 배포할 타겟(및 서브 타겟) 플랫폼을 지정할 수 있습니다.
요청된 플랫폼이 Build Settings 다이얼로그에 현재 설정된 플랫폼과 다를 수 있습니다. 그러나 빌드 스크립트를 트리거하기 전에 항상 Build Settings의 설정이 에셋 번들 빌드의 설정과 일치하도록 해야 합니다. 타겟이 일치하지 않으면 Unity는 새 플랫폼을 반영하도록 에디터 스크립트를 다시 컴파일해야 하며, 플랫폼별 표현이 있는 텍스처와 같은 에셋에 대한 임포트도 트리거할 수 있습니다. 그런 다음 빌드가 끝나면 원래 타겟 플랫폼과 일치하도록 상태를 다시 복원합니다. 일반적으로 이 방법은 원활하게 작동하지만, 빌드 반복을 많이 수행할 경우 각 빌드에 상당한 시간이 추가될 수 있습니다. 또한 BuildPipeline.BuildAssetBundles에 대한 호출이 포함된 스크립트는 지정된 빌드 타겟이 아닌 현재 타겟에 대해 컴파일된 스크립트 도메인에서 계속 실행됩니다. 이는 빌드 스크립트 또는 콜백 스크립트에서 플랫폼별 코드나 어셈블리를 사용할 수 있을 것으로 예상하는 경우에만 문제가 됩니다. 대부분의 프로젝트에서는 이러한 미묘한 차이가 문제가 되지 않습니다. 하지만 이러한 위험을 방지하려면 빌드 중에 실행되는 모든 코드가 플랫폼 조건부 컴파일(#ifdef 문)을 사용하는 대신 항상 타겟을 동적으로 확인해야 합니다(예: if
문 사용).
커맨드 라인 빌드의 경우 빌드하려는 타겟과 일치하도록 --buildTarget
커맨드 라인 인자를 사용해야 합니다.
Unity의 에셋 번들 시스템은 오브젝트가 에셋 번들에 빌드될 때 해당 오브젝트의 모든 종속성을 발견합니다.이는 에셋 데이터베이스를 사용하여 수행됩니다.이 종속성 정보는 에셋 번들에 포함될 오브젝트 세트를 결정하는 데 사용됩니다.
에셋 번들에 대한 할당은 에셋 수준에서 이루어집니다.에셋 번들에 명시적으로 할당된 에셋 내부의 오브젝트는 해당 단일 에셋 번들에만 빌드됩니다.BuildPipeline.BuildAssetBundles의 어떤 서명이 호출되는지에 따라, 에셋의 AssetImporter.assetBundleName 프로퍼티를 비어 있지 않은 문자열로 설정하거나 이것을 AssetBundleBuild.assetNames에 나열함으로써 에셋이 “명시적으로 할당됩니다”.
에셋 번들에 명시적으로 할당되지 않은 에셋의 일부인 오브젝트는 해당 오브젝트를 참조하는 오브젝트가 포함된 각 에셋 번들에 포함됩니다.
즉, 두 개의 다른 오브젝트가 두 개의 다른 에셋 번들에 할당되었지만 둘 다 공통 종속성 오브젝트에 대한 레퍼런스가 있는 경우 해당 종속성 오브젝트가 두 에셋 번들 모두에 복사됩니다.중복된 종속성도 인스턴스화되므로 종속성 오브젝트의 두 사본은 다른 식별자를 가진 다른 오브젝트로 간주됩니다.이렇게 하면 애플리케이션의 에셋 번들의 총 크기가 증가합니다.또한 애플리케이션이 두 부모를 모두 로드하는 경우 오브젝트의 서로 다른 두 사본이 메모리에 로드됩니다.
이 문제는 아래의 몇 가지 방법으로 해결할 수 있습니다.
서로 다른 에셋 번들에 내장된 오브젝트가 종속성을 공유하지 않도록 합니다. 종속성을 공유하는 오브젝트는 종속성 중복 없이 동일한 에셋 번들에 포함시킬 수 있습니다.
종속성을 공유하는 두 에셋 번들이 동시에 로드되지 않도록 에셋 번들을 분할합니다.
모든 종속성 에셋이 자체적인 에셋 번들에 내장되도록 합니다. 그러면 에셋이 중복될 위험이 완전히 배제되지만, 애플리케이션이 에셋 번들 간 종속성을 추적해야 하고 AssetBundle.LoadAsset API를 호출하기 전에 올바른 에셋 번들이 로드되는지 확인해야 하는 복잡성이 발생합니다.
오브젝트 종속성은 UnityEditor 네임스페이스에 있는 AssetDatabase API를 통해 추적됩니다.네임스페이스에서 알 수 있듯이 이 API는 런타임이 아닌 Unity 에디터에서만 사용할 수 있습니다.AssetDatabase.GetDependencies는 특정 오브젝트 또는 에셋의 모든 즉각적인 종속성을 찾는 데 사용할 수 있습니다.이러한 종속성에는 자체 종속성이 있을 수 있으므로 재귀적 계산이 될 수 있다는 점에 유의하십시오.에셋을 에셋 번들에 할당하는 것은 BuildPipeline.BuildAssetBundles를 호출할 때 에셋 번들 빌드 구조의 배열을 전달하여 명시적으로 정의하거나, AssetImporter API를 사용하여 쿼리할 수 있습니다.에셋 번들의 모든 직접 또는 간접 종속성이 에셋 번들에 할당되거나 두 개의 에셋 번들이 에셋 번들에 할당되지 않은 종속성을 공유하지 않도록 보장하는 에디터 스크립트를 작성할 수 있습니다.
참고:Addressables 패키지로 에셋 번들을 빌드할 때 ‘Addressables Analyze’ 창을 사용하여 중복된 에셋을 발견할 수 있습니다.
이어지는 섹션에서는 에셋 종속성 계산 코드를 자동 생성된 스프라이트 아틀라스와 함께 사용할 경우에 발생할 수 있는 문제점에 대해 설명합니다.
자동 생성 스프라이트 아틀라스는 스프라이트 아틀라스가 생성된 스프라이트 오브젝트가 포함된 에셋 번들에 할당됩니다. 스프라이트 오브젝트가 여러 에셋 번들에 할당된 경우, 스프라이트 아틀라스가 에셋 번들에 할당되지 않고 중복됩니다. 스프라이트 오브젝트가 에셋 번들에 할당되지 않은 경우, 스트라이트 아틀라스도 에셋 번들에 할당되지 않습니다.
스프라이트 아틀라스가 중복되지 않도록 하려면 모든 동일한 스프라이트 아틀라이스 안에 태그된 스프라이트가 동일한 에셋 번들에 할당되는지 확인합니다.
Android 생태계에서는 기기 단편화가 심하기 때문에 텍스처를 여러 가지 포맷으로 압축해야 하는 경우가 많습니다. 모든 Android 기기는 ETC1을 지원하지만, ETC1은 알파 채널이 있는 텍스처를 지원하지 않습니다.
에셋 번들 배리언트를 사용하려면 ETC1을 사용하여 깔끔하게 압축할 수 없는 모든 텍스처를 텍스처 전용 에셋 번들로 분리해야 합니다. 그런 다음 DXT5, PVRTC와 같은 공급업체별 텍스처 압축 포맷을 사용해서 이러한 에셋 번들의 배리언트를 충분히 생성하여 ETC2를 지원하지 않는 일부 Android 생태계를 지원합니다. 각 에셋 번들 배리언트에 대해 포함된 텍스처의 TextureImporter 설정을 해당 배리언트에 적합한 압축 포맷으로 변경합니다.
런타임 시 다양한 텍스처 압축 포맷 지원 여부를 SystemInfo.SupportsTextureFormat API를 사용하여 인식할 수 있습니다. 이 정보를 사용해 지원되는 포맷으로 압축된 텍스터가 포함되어 있는 에셋 번들 배리언트를 선택하고 로드해야 합니다.
Android 텍스처 압축 포맷에 대한 자세한 내용은 여기에서 확인할 수 있습니다.
에셋 번들을 빌드할 때 Unity는 해당 번들의 정보를 사용하여 컴파일할 셰이더 배리언트를 선택합니다.여기에는 에셋 번들에 있는 씬, 머티리얼, 그래픽스 설정 및 ShaderVariantCollections에 대한 정보가 포함됩니다.
별도의 빌드 파이프라인은 다른 파이프라인과 독립적으로 자체 셰이더를 컴파일합니다.플레이어 빌드와 어드레서블 빌드가 모두 셰이더를 참조하는 경우 Unity는 각 파이프라인에 대해 하나씩 두 개의 셰이더 사본을 컴파일합니다.
이 프로세스에서는 키워드, 텍스처 또는 코드 실행으로 인한 변경 사항과 같은 런타임 정보는 고려하지 않습니다.빌드에 특정 셰이더를 포함하려면 원하는 셰이더가 포함된 ShaderVariantCollection을 포함하거나 그래픽 설정의 항상 포함된 셰이더 목록에 셰이더를 추가하여 수동으로 빌드에 셰이더를 포함하십시오.