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.
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.
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:
The manifest files generated alongside each AssetBundle give some human-readable details about the contents of an AssetBundle.
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 scriptsA piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary 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 ShaderA program that runs on the GPU. More info
See in Glossary 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.
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.
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 in the Build ProfilesA set of customizable configuration settings to use when creating a build for your target platform. More info
See in Glossary window. However you should always make sure the settings in Build Profiles 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.
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.
There are several ways to address this problem:
Ensure that Objects built into different AssetBundles do not share dependencies. Any Objects which do share dependencies can be placed into the same AssetBundle without duplicating their dependencies.
Segment AssetBundles so that no two AssetBundles that share a dependency will be loaded at the same time.
Ensure that all dependency assets are built into their own AssetBundles. This entirely eliminates the risk of duplicated assets, but also introduces complexity. The application must track dependencies between AssetBundles, and ensure that the right AssetBundles are loaded before calling any 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 dependenciesAn indirect, or transitive dependency occurs when your project requests a package which itself “depends on” another package. For example, if your project depends on the alembic@1.0.7
package which in turn depends on the timeline@1.0.0
package, then your project has an direct dependency on Alembic and an indirect dependency on Timeline. More info
See in Glossary 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.
The following sections describe a quirk of asset dependency calculation code when used in conjunction with automatically-generated spriteA 2D graphic objects. If you are used to working in 3D, Sprites are essentially just standard textures but there are special techniques for combining and managing sprite textures for efficiency and convenience during development. More info
See in Glossary atlases.
Any automatically-generated sprite atlasA utility that packs several sprite textures tightly together within a single texture known as an atlas. More info
See in Glossary will be assigned to the AssetBundle containing the Sprite Objects from which the sprite atlas was generated. If the sprite Objects are assigned to multiple AssetBundles, then the sprite atlas will not be assigned to an AssetBundle and will be duplicated. If the Sprite Objects are not assigned to an AssetBundle, then the sprite atlas will also not be assigned to an AssetBundle.
To ensure that sprite atlases are not duplicated, check that all sprites tagged into the same sprite atlas are assigned to the same AssetBundle.
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 compressionA method of storing data that reduces the amount of storage space it requires. See Texture Compression, Animation Compression, Audio Compression, Build Compression.
See in Glossary formats such as DXT5, PVRTC. For each AssetBundle Variant, change the included textures’ TextureImporter settings to the compression format appropriate to the Variant.
At runtime, support for the different texture compression3D Graphics hardware requires Textures to be compressed in specialized formats which are optimized for fast Texture sampling. More info
See in Glossary formats can be detected using the SystemInfo.SupportsTextureFormat API. This information should be used to select and load the AssetBundle Variant containing textures compressed in a supported format.
More information on Android texture compression formats can be found here.
When you build an AssetBundle, Unity uses information in that bundle to select which shader variants to compile. This includes information about the scenesA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
See in Glossary, 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.
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.
When you visit any website, it may store or retrieve information on your browser, mostly in the form of cookies. This information might be about you, your preferences or your device and is mostly used to make the site work as you expect it to. The information does not usually directly identify you, but it can give you a more personalized web experience. Because we respect your right to privacy, you can choose not to allow some types of cookies. Click on the different category headings to find out more and change our default settings. However, blocking some types of cookies may impact your experience of the site and the services we are able to offer.
More information
These cookies enable the website to provide enhanced functionality and personalisation. They may be set by us or by third party providers whose services we have added to our pages. If you do not allow these cookies then some or all of these services may not function properly.
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us to know which pages are the most and least popular and see how visitors move around the site. All information these cookies collect is aggregated and therefore anonymous. If you do not allow these cookies we will not know when you have visited our site, and will not be able to monitor its performance.
These cookies may be set through our site by our advertising partners. They may be used by those companies to build a profile of your interests and show you relevant adverts on other sites. They do not store directly personal information, but are based on uniquely identifying your browser and internet device. If you do not allow these cookies, you will experience less targeted advertising. Some 3rd party video providers do not allow video views without targeting cookies. If you are experiencing difficulty viewing a video, you will need to set your cookie preferences for targeting to yes if you wish to view videos from these providers. Unity does not control this.
These cookies are necessary for the website to function and cannot be switched off in our systems. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms. You can set your browser to block or alert you about these cookies, but some parts of the site will not then work. These cookies do not store any personally identifiable information.