A content directory is the output of the content build process, similar to the folder that contains the .bundle files and manifest when using AssetBundles. You don’t assign assets to a content directory in the Unity Editor, but create a ScriptableObject instance which acts as a root asset that references the content you want to include in your application. You then pass the root asset path to BuildPipeline.BuildContentDirectory to produce a built content folder.
A root asset is a ScriptableObject asset in your project that you use to define which content to include in a content build.
If you’re moving from the AssetBundle system, root assets don’t need to mirror AssetBundles. For example, if you previously had ten AssetBundles, you don’t need ten root assets because the content in a content directory can be loaded and unloaded independently without having to load other content in the root asset. One root asset for all content suits most projects, and if necessary, you can create more for specific content such as DLC.
Unity loads root assets into memory automatically when you register a content directory with ContentLoadManager.RegisterContentDirectory, so it’s best practice to avoid direct references to large assets.
For an example, refer to Create a ScriptableObject to define the root asset.
Content directories are designed to be a replacement for the AssetBundle system. The concept of assigning assets to be built in separate content builds remains the same, but the process differs as follows:
| Workflow | AssetBundles | Content directories |
|---|---|---|
| Creation | Create named AssetBundles in the Editor, or .meta files. |
Create ScriptableObject instances and pass their paths as root assets in the build script. |
| Assigning assets | Assign each asset to a specific AssetBundle. | Reference assets from the ScriptableObject instances. |
| Building | Run BuildPipeline.BuildAssetBundles. |
Run BuildPipeline.BuildContentDirectory with an output folder path and rootAssetPaths. |
| Loading content | Each dependent AssetBundle loaded explicitly with AssetBundle.LoadFromFile and similar methods. |
All content available with ContentLoadManager.RegisterContentDirectory. |
| Loading individual assets | Use AssetBundle.LoadAsset. |
Use Loadable<T>. |
| Loading 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 |
Load through SceneManager by path. |
Load through SceneManager by LoadableSceneId. |
Important: You can only use content directories to create local content builds that you distribute with the Player build of your application. If you want to distribute content builds remotely, or download content after the user installs a Player, then you must create your own mechanism for distributing content directories, or use the AssetBundle system.
To create content directories, perform the following steps:
The following is an example which defines a root asset for an optional DLC pack. It uses three ways to include content in the build:
Loadable<GameObject> for a bonus prefab you load on demand at runtime.LoadableSceneId for a bonus level scene.ScriptableObject.For more information on how to reference assets, refer to Reference content in a content directory.
Save the following as DLCRootAsset.cs anywhere in the Assets folder of your project.
using UnityEngine;
using Unity.Loading;
// Lightweight metadata asset that the root asset references directly.
[CreateAssetMenu(fileName = "DLCMetadata", menuName = "Content/DLC Metadata")]
public class DLCMetadata : ScriptableObject
{
public string description;
// Stored as a string because Unity doesn't serialize System.DateTime.
public string expirationDate;
public int difficulty;
}
// Defines the name of the menu options as they appear in the Editor.
[CreateAssetMenu(fileName = "DLCRootAsset", menuName = "Content/DLC Root Asset")]
public class DLCRootAsset : ScriptableObject
{
// Loadable: included in the build; load when needed with bonusPrefab.Load().
public Loadable<GameObject> bonusPrefab;
// Scene reference: included in the build; load with SceneManager when the directory is registered.
public LoadableSceneId bonusLevel;
// Direct reference to another lightweight ScriptableObject is fine here, such as metadata.
public DLCMetadata metadata;
}
If you have a large amount of content, you don’t have to define all Loadable<T> references on a single root asset. You can create a hierarchy of ScriptableObject instances where the root asset holds direct references to other ScriptableObject instances, each of which tracks a different category of content. Only the top-level ScriptableObject in the hierarchy needs to be the root asset passed to BuildPipeline.BuildContentDirectory. For more information, refer to Build the content directory.
[CreateAssetMenu]).DLCRootAsset) and place it at a stable path such as Assets/DLC/DLCRootAsset.asset.DLCMetadata asset in the InspectorA Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More infoThe .asset path is what you pass to the build API, for example:
var parameters = new BuildContentDirectoryParameters
{
outputPath = "Builds/DLC_Expansion",
rootAssetPaths = new[] { "Assets/DLC/DLCRootAsset.asset" }
};
BuildPipeline.BuildContentDirectory(parameters);
Unity then follows references from the content directory and includes the metadata asset, bonus prefab, and bonus level scene in the content directory build.
The following is an example of an Editor script that uses the previous steps to call the build API and create a content directory:
using UnityEditor;
using UnityEditor.Build.Reporting;
public static class BuildDLCRootAsset
{
[MenuItem("Build/Content Directories/DLC Expansion")]
public static void Build()
{
var parameters = new BuildContentDirectoryParameters
{
// Folder for the built content directory (created if it does not exist).
// Typically should be outside the Assets folder.
outputPath = "Builds/DLC_Expansion",
// Project paths to ScriptableObject root assets for this pack.
// Unity includes each root and every asset they reference (direct, Loadable, scenes).
rootAssetPaths = new[]
{
"Assets/DLC/DLCRootAsset.asset"
},
// Optional build flags (for example BuildContentOptions.CleanBuildCache).
// See BuildContentOptions in the Scripting Reference.
options = BuildContentOptions.None,
};
// Uses the active build target from Build Profiles.
BuildReport report = BuildPipeline.BuildContentDirectory(parameters);
if (report.summary.result == BuildResult.Succeeded)
UnityEngine.Debug.Log($"DLC content directory built to: {parameters.outputPath}");
}
}
You can then create a content build from the menu item the script adds under Build. Unity adds the content directory to the Builds folder of your project, as defined by outputPath.
For more information on the optional build flags, refer to the BuildContentOptions API documentation.
To create another content directory, run BuildContentDirectory again with a different outputPath and different rootAssetPaths.
To verify the build process was successful, you can check the build result as follows:
BuildReport.summary.result. For example, the previous build script logs a message when report.summary.result equals BuildResult.Succeeded.When the build succeeds, Unity writes the content directory to the folder under outputPath, including a build manifest file. Distribute every file in this folder along with the Player build. To package the output into a Player build from a script, refer to Create a custom build script.