Build assets into AssetBundles
Create build scripts and compile assets into AssetBundle files.
Read time 6 minutesLast updated 3 days ago
To build assets into an AssetBundle, you must assign assets to an AssetBundle, either in the Unity Editor or through a script. You can then create and use a script to build the AssetBundles. For information on the best approaches for organizing assets into AssetBundles, refer to Preparing assets for AssetBundles.
AssetBundle build script
To build AssetBundles, you must create a build script and place it a folder called in the folder.
EditorAssetsThe following script is an example of an AssetBundle build script. It adds a menu item at the bottom of the Assets menu called Build AssetBundles. When you select Build AssetBundles the method is called. A progress bar appears while the build takes all the assets you labeled with an AssetBundle name and uses them to populate AssetBundles at the path that defines.
BuildAllAssetBundlesassetBundleDirectoryusing UnityEditor; using System.IO; public class CreateAssetBundles { [MenuItem("Assets/Build AssetBundles")] static void BuildAllAssetBundles() { // Ensure the AssetBundles directory exists, and if it doesn't, create it. string assetBundleDirectory = "Assets/AssetBundles"; if (!Directory.Exists(assetBundleDirectory)) Directory.CreateDirectory(assetBundleDirectory); // Build all AssetBundles and place them in the specified directory. BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows); } }
The script has the following arguments:
- : The directory to output the AssetBundles to within the current Unity project. The folder doesn't need to be in the
assetBundleDirectoryfolder. In the code example, it creates the folder on demand if it doesn't exist.Assets - : The default value for the build options argument. You can use this argument to specify one or more flags to enable a variety of optional behaviours. For example, this argument controls the choice of compression algorithm. For a full list of options available refer to the
BuildAssetBundleOptions.NoneAPI documentation.BuildAssetBundleOptions - : Defines the target platform for the AssetBundles. Alternatively, you can call
BuildTarget.StandaloneWindows, which returns the platform profile currently set as active in the Build Profiles window.EditorUserBuildSettings.activeBuildTarget
Build subsets of AssetBundles
When you give the method no specific AssetBundle names, it builds all AssetBundles defined in the project. If you only want to build a subset of AssetBundles, you query the AssetDatabase for defined AssetBundles and then pass a filtered list to the build pipeline.
BuildPipeline.BuildAssetBundlesThe following script demonstrates how to retrieve all AssetBundle names and their assigned assets, allowing you to filter or modify the list before building:
using UnityEditor; using System.IO; using UnityEngine; using System.Collections.Generic; public class BuildSubsetAssetBundles { [MenuItem("Assets/Build Selected AssetBundles")] static void BuildSpecificAssetBundles() { string assetBundleDirectory = "Assets/AssetBundles"; if (!Directory.Exists(assetBundleDirectory)) { Directory.CreateDirectory(assetBundleDirectory); } List<AssetBundleBuild> builds = new List<AssetBundleBuild>(); string[] allAssetBundleNames = AssetDatabase.GetAllAssetBundleNames(); // Example: Only build AssetBundles that start with "environment" foreach (string bundleName in allAssetBundleNames) { if (bundleName.StartsWith("environment")) { AssetBundleBuild build = new AssetBundleBuild { assetBundleName = bundleName, assetNames = AssetDatabase.GetAssetPathsFromAssetBundle(bundleName) }; builds.Add(build); } } if (builds.Count > 0) { BuildPipeline.BuildAssetBundles(assetBundleDirectory, builds.ToArray(), BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows); Debug.Log($"Built {builds.Count} specific AssetBundles."); } else { Debug.Log("No AssetBundles matching criteria found to build."); } } [MenuItem("Assets/Log All AssetBundle Assignments")] static void LogAllAssetBundleAssignments() { string[] allAssetBundleNames = AssetDatabase.GetAllAssetBundleNames(); Debug.Log($"Total AssetBundles Defined: {allAssetBundleNames.Length}"); foreach (string bundleName in allAssetBundleNames) { string[] assetPaths = AssetDatabase.GetAssetPathsFromAssetBundle(bundleName); Debug.Log($"AssetBundle: {bundleName} (Assets: {assetPaths.Length})"); foreach (string path in assetPaths) { Debug.Log($" - {path}"); } } } }
This approach allows your script to respect existing Inspector assignments while giving you granular control over which AssetBundles are built.
Perform a clean build
When you create an official AssetBundle release, perform a clean build to ensure Unity rebuilds all content during the build process. To perform a clean build, pass the flag as an option to .
BuildAssetBundleOptions.ForceRebuildAssetBundleBuildPipeline.BuildAssetBundlesIn some projects, you can delete the directory to force a full recompilation of shaders, or to reclaim disk space from obsolete shader data. However, deleting the folder increases the time it takes for Unity to create another build.
Library/ShaderCacheShaderCacheFor more information on clean builds, refer to Create a clean build.
Changing target platform
The API allows you to specify the target and sub target platform for deploying AssetBundles.
BuildPipeline.BuildAssetBundlesIf the specified target platform differs from the one configured in Build Profiles, Unity must recompile Editor scripts and reimport assets such as textures that have platform-specific representations. After the build is complete, Unity restores the original target platform settings.
This process can significantly increase build times. Additionally, the script containing the call continues to execute as compiled for the current target platform, not the specified build target. This can cause issues if the build script or callback scripts rely on platform-specific code or assemblies.
BuildPipeline.BuildAssetBundlesTo avoid this issue, ensure that any code executed during a build dynamically checks the target platform (for example, using statements) rather than relying on platform-specific conditional compilation (such as, statements). It's best practice to always set the target to the desired target, then launch the script that builds AssetBundles to avoid any issues from code outside your control such as build callbacks inside packages.
if#ifdefFor command line builds, use the or command line argument to align the target platform with your build requirements. For more information, refer to Create a build from the command line.
--buildTarget-activeBuildProfileRebuilding assets incrementally
Each AssetBundle has a hash that Unity uses to determine whether it needs to be rebuilt. Unity determines how to rebuild AssetBundles incrementally as follows:
- If a file from a previous build of that AssetBundle exists, Unity compares the IncrementalBuildHash hashes from both builds.
.manifest - If the AssetBundle hashes match, then Unity calculates and compares their type tree hashes. Unity uses as a secondary hash to detect whether any objects used in the AssetBundle have newer serialization formats. You can ignore this check by specifying the
TypeTreeHashflag.BuildAssetBundleOptions.IgnoreTypeTreeChanges - If the AssetBundle hash and the type tree hash don't match, then Unity rebuilds the AssetBundle unless you've specified which rebuilds the AssetBundle every time.
BuildAssetBundleOptions.ForceRebuildAssetBundle, - Unity serializes the newly calculated hash values into the new AssetBundle's file.
.manifest
The AssetBundle IncrementalBuildHash considers inputs such as the target platform, included assets, dependencies, build options, and platform-specific settings like mesh stripping and lighting configurations. However, this hash doesn't consider every possible build influence, which might lead to crashes or unexpected failures if the incremental build systems doesn't detect all changes. Use incremental builds for internal development but perform a clean build when creating a release build.