Version: 2023.2
언어: 한국어
에셋 번들로 패치
에셋 번들 다운로드 무결성 및 보안

문제 해결

Tips for Investigating AssetBundle Build results

The following methods can be useful for collecting information after an AssetBundle build has run. These can be useful when investigating unexpected behavior, or when tuning the assignment of assets to bundles.

Logs

The Unity Editor log collects information during a build, such as warning or error messages. And at the end of an AssetBundle build there is a detailed message logged that shows information about the type and size breakdown for each AssetBundle.

Build Report

AssetBundle builds generate a BuildReport which is a Unity SerializedFile written to Library/LastBuild.buildreport inside the project directory. This file is useful for seeing a summary of the timings for build steps and a detailed view of the contents of the AssetBundle. The BuildReport API can be used to read information from the BuildReport file.

Two unsupported tools are available for viewing the content of the BuildReport:

.manifest files

The manifest files generated alongside each AssetBundle give some human-readable details about the contents of an AssetBundle.

Clean Builds

To speed up iteration time Unity supports incremental building for AssetBundles. For example, elements from past builds can be reused for aspects of the project that have not changed since the last build. While this can speed up iteration time, there are a few limitations on its ability to detect changes in the input, especially if scripts run by build callbacks are changing data in a non-deterministic way. Therefore, you should always perform a clean build rather than an incremental build when you are building an official release of your AssetBundles.

The BuildAssetBundleOptions.ForceRebuildAssetBundle flag, passed as an option to BuildPipeline.BuildAssetBundles(), is the recommended way to perform a clean build.

In some rare cases it might also be desirable to erase the Library/ShaderCache directory. This cache is not flushed when BuildAssetBundleOptions.ForceRebuildAssetBundle is specified. On many projects the Shader compilation phase can be quite a time consuming step, so erasing the cache can add a lot of time to the next Player or AssetBundle build.

Alternatively, the most reliable way to perform a completely clean build is to stop Unity, erase the project’s Library directory, and then restart Unity. This can be very time consuming because all the project Assets need to be reimported and other data is regenerated.

Examining AssetBundle contents

In some cases you might want to look directly inside an AssetBundle, or compare the contents of two AssetBundles.

The Unity Editor installation includes the WebExtract and Binary2Text executables. You can use WebExtract to extract the files that are nested inside the AssetBundle, similar to extracting a zip file. Then you can use Binary2Text to produce a text format dump of the contents of a binary SerializedFile. Its output is somewhat similar to the yaml format used by Unity.

Another similar mechanism to see the content of an AssetBundle’s SerializedFiles in text form is to run UnityDataTools with its “dump” argument.

The raw content of Serialized files tends to be very technical and very large, especially when Shaders or Meshes or binary data is present. But these dumps can also provide a wealth of information if you can narrow down a problem to specific objects within a file. Comparing the extracted content of two similar AssetBundles using a diff tool can be a convenient way to narrow down the precise differences.

Target Switching

The arguments to the BuildPipeline.BuildAssetBundles API lets you specify the target (and subtarget) platform where you will be deploying the AssetBundles.

It is possible the requested platform is different from what is currently configured on the Build Settings dialog. However you should always make sure the settings in the Build Settings match the settings for your AssetBundle build, prior to triggering your build script. When the targets don’t match, Unity must recompile the Editor scripts to reflect the new platform and also potentially trigger imports for Assets like textures that have platform specific representations. Then at the end of the build it will restore the state back to match the original target platform. Typically this works fine, but it can add significant time to each build, which can add up when performing a lot of build iterations. Furthermore the script that contains the call to BuildPipeline.BuildAssetBundles will continue to execute in the script domain as compiled for the current target, not the specified build target. This is only a problem if the build script, or callback scripts, expects platform-specific code or assemblies to be available. For many projects this subtle difference will not be an issue. But to help avoid this sort of pitfall you should always make sure that any code executed during a build checks the target dynamically (e.g. with if statements) instead of using platform conditional compilation (#ifdef statements).

For command line builds the --buildTarget command line argument should be used to match the target you want to build.

Asset Duplication

Unity’s AssetBundle system will discover all dependencies of an Object when the Object is built into an AssetBundle. This is done using the Asset Database. This dependency information is used to determine the set of Objects that will be included in an AssetBundle.

Assignment to AssetBundles happens at the Asset level. The Objects inside an Asset that is explicitly assigned to an AssetBundle will only be built into that single AssetBundle. Depending which signature of BuildPipeline.BuildAssetBundles is called, an Asset is “explicitly assigned” either by setting the Asset’s AssetImporter.assetBundleName property to a non-empty string, or by listing it in AssetBundleBuild.assetNames.

Any Object that is part of an Asset that is not explicitly assigned in an AssetBundle will be included in each AssetBundle that contains any Objects that reference it.

In other words, if two different Objects are assigned to two different AssetBundles, but both have references to a common dependency Object, then that dependency Object will be copied into both AssetBundles. The duplicated dependency will also be instanced, meaning that the two copies of the dependency Object will be considered different Objects with a different identifiers. This will increase the total size of the application’s AssetBundles. This will also cause two different copies of the Object to be loaded into memory if the application loads both of its parents.

이 문제는 아래의 몇 가지 방법으로 해결할 수 있습니다.

  1. 서로 다른 에셋 번들에 내장된 오브젝트가 종속성을 공유하지 않도록 합니다. 종속성을 공유하는 오브젝트는 종속성 중복 없이 동일한 에셋 번들에 포함시킬 수 있습니다.

    • 공유되는 종속성이 많은 프로젝트에는 이 메서드가 일반적으로 실용적이지 않습니다. 이 경우 항상 다시 빌드해야 하므로 불편하고 매번 다운로드해야 하는 비효율적인 단일 에셋 번들이 생길 수 있기 때문입니다.
  2. 종속성을 공유하는 두 에셋 번들이 동시에 로드되지 않도록 에셋 번들을 분할합니다.

    • This method may work for certain types of projects, such as level-based games. However there is still a trade-off, because duplicated objects will increase the build time and sizes of the project’s AssetBundles, and could impact loading times.
  3. 모든 종속성 에셋이 자체적인 에셋 번들에 내장되도록 합니다. 그러면 에셋이 중복될 위험이 완전히 배제되지만, 애플리케이션이 에셋 번들 간 종속성을 추적해야 하고 AssetBundle.LoadAsset API를 호출하기 전에 올바른 에셋 번들이 로드되는지 확인해야 하는 복잡성이 발생합니다.

Object dependencies are tracked via the AssetDatabase API, located in the UnityEditor namespace. As the namespace implies, this API is only available in the Unity Editor and not at runtime. AssetDatabase.GetDependencies can be used to locate all of the immediate dependencies of a specific Object or Asset. Note that these dependencies may have their own dependencies so this can be a recursive calculation. The assignment of Assets to AssetBundles will either be defined explicitly by passing arrays of AssetBundleBuild structures when calling BuildPipeline.BuildAssetBundles, or can be queried using the AssetImporter API. It is possible to write an Editor script that ensures that all of an AssetBundle’s direct or indirect dependencies are assigned to AssetBundles, or that no two AssetBundles share dependencies that have not been assigned to an AssetBundle.

Note: When building AssetBundles with the Addressables package, the Addressables Analyze window can be used to discover duplicated assets.

Sprite Atlas Duplication

The following sections describe a quirk of asset dependency calculation code when used in conjunction with automatically-generated sprite atlases.

자동 생성 스프라이트 아틀라스는 스프라이트 아틀라스가 생성된 스프라이트 오브젝트가 포함된 에셋 번들에 할당됩니다. 스프라이트 오브젝트가 여러 에셋 번들에 할당된 경우, 스프라이트 아틀라스가 에셋 번들에 할당되지 않고 중복됩니다. 스프라이트 오브젝트가 에셋 번들에 할당되지 않은 경우, 스트라이트 아틀라스도 에셋 번들에 할당되지 않습니다.

스프라이트 아틀라스가 중복되지 않도록 하려면 모든 동일한 스프라이트 아틀라이스 안에 태그된 스프라이트가 동일한 에셋 번들에 할당되는지 확인합니다.

Android Textures

Due to heavy device fragmentation in the Android ecosystem, it’s often necessary to compress textures into several different formats. While all Android devices support ETC1, ETC1 doesn’t support textures with alpha channels.

To use AssetBundle Variants, all textures that can’t be cleanly compressed using ETC1 must be isolated into texture-only AssetBundles. Next, create sufficient variants of these AssetBundles to support the non-ETC2-capable slices of the Android ecosystem, using vendor-specific texture compression formats such as DXT5, PVRTC. For each AssetBundle Variant, change the included textures’ TextureImporter settings to the compression format appropriate to the Variant.

런타임 시 다양한 텍스처 압축 포맷 지원 여부를 SystemInfo.SupportsTextureFormat API를 사용하여 인식할 수 있습니다. 이 정보를 사용해 지원되는 포맷으로 압축된 텍스터가 포함되어 있는 에셋 번들 배리언트를 선택하고 로드해야 합니다.

Android 텍스처 압축 포맷에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

Interactions between Shaders and AssetBundles

When you build an AssetBundle, Unity uses information in that bundle to select which shader variants to compile. This includes information about the scenes, materials, Graphics Settings, and ShaderVariantCollections in the AssetBundle.

Separate build pipelines compile their own shaders independently of other pipelines. If both a Player build and an Addressables build reference a shader, Unity compiles two separate copies of the shader, one for each pipeline.

This process doesn’t account for any runtime information such as keywords, textures, or changes due to code execution. If you want to include specific shaders in your build, either include a ShaderVariantCollection with the desired shaders, or include the shader in your build manually by adding it to the Always Included Shaders list in your graphics settings.

에셋 번들로 패치
에셋 번들 다운로드 무결성 및 보안
Copyright © 2023 Unity Technologies
优美缔软件(上海)有限公司 版权所有
"Unity"、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属机构在美国及其他地区的商标或注册商标。其他名称或品牌是其各自所有者的商标。
公安部备案号:
31010902002961