Version: 2023.1
言語: 日本語
アセットバンドルにパッチを適用する
アセットバンドルのダウンロードの整合性とセキュリティ

トラブルシューティング

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 APIs の呼び出しが行われる前に正しいアセットバンドルが確実に読み込まれようにしなければなりません。

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 で判定できます。この情報は、対応された形式で圧縮されたテクスチャを含む AssetBundle Variant の選択と読み込みに使用されます。

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