文档

Unity Engine


User Manual

Script Reference

Unity Engine


Include scenes in a content build

Use loadable references to reference and load scenes from a content directory at runtime.
阅读时间7 分钟最后更新于 1 个月前

Unity builds the scenes in the Scene List of the
Build Profile

?

window directly into a Player build rather than including them in a content build. When the Player starts up, Unity automatically loads the first scene in the list.
To keep builds efficient, create one startup scene in the Scene List which serves as access to the content in a content directory build. This approach avoids asset duplication and keeps all content within the content directory build.
This single startup scene typically contains one or more MonoBehaviour components that register the content directory at runtime, then load one or more scenes and other initial content from it.

Include scenes in a content directory

To include scenes in a content directory, use
LoadableSceneId
. You can also use this struct to reference those scenes from scripts and from the Unity Editor.
You can use
LoadableSceneId
as a field type in
MonoBehaviour
and
ScriptableObject
-derived classes. You can assign a scene to a field of type
LoadableSceneId
while authoring content in the Editor, either through the Inspector or from scripts.
// Example of assigning a LoadableSceneId field from scriptingmyMonoBehaviour.m_Scene = LoadableSceneIdEditorUtility.CreateLoadableSceneId(scenePath);
Internally
LoadableSceneId
uses the Asset Database GUID as a unique identifier for the scene. This means that the reference continues to work even if you rename the scene asset or move it within the project.
Unity finds scenes the same way it finds any other content by starting at the root assets and recursively following tracked references.
LoadableSceneId
references aren't limited to root assets, so the build includes any scene referenced by a
LoadableSceneId
field on any object Unity reaches from the root assets. Unity also walks into each included scene to pull in the dependencies that scene requires. For more information, refer to Reference content in a content directory.
At runtime and in Play mode, you can use
LoadableSceneId
fields with the
SceneManager
API
to load and unload scenes. You must register the content directory containing the scene before loading the scene. For more information on registering content directories, refer to Load content directories.
注意
Loadable<T>
isn't compatible with scenes, because your application might need to load scenes multiple times.
LoadableSceneId
is the scene-oriented counterpart to
LoadableObjectId
, which is used for assets.

Runtime loading of scenes

To load scenes in the Player or Play mode, call the following:
AsyncOperation SceneManager.LoadSceneAsync(Unity.Loading.LoadableSceneId, LoadSceneParameters);
The call returns an
AsyncOperation
instance that you can use to track the asynchronous load. A common pattern is to subscribe to
AsyncOperation.completed
and then call
SceneManager.GetSceneByLoadableSceneId(loadableSceneId)
from the callback to retrieve the loaded
Scene
.
You can load scenes one by one, or additively through the
LoadSceneParameters
argument
. In
Single
mode all other open scenes are closed. In
Additive
mode, scenes that are already loaded remain open. Refer to
SceneManagement.LoadSceneMode
for more information.
If two
LoadableSceneId
values reference the same scene and you call
LoadSceneAsync
on each in
Additive
mode, Unity loads the scene twice as two distinct scene instances.
To unload scenes, call
UnloadSceneAsync
.
For example, a startup scene can contain a MonoBehaviour with
LoadableSceneId
fields that reference other scenes. You can assign the scenes in the Inspector while authoring, and at runtime scripts can load and unload scenes in response to events such as character movement or button presses.
The following example loads two scenes additively at startup and unloads one in response to an event:
using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; using Unity.Loading; public class SceneLoader : MonoBehaviour { // Use the Inspector to assign scenes to these fields. [SerializeField] LoadableSceneId m_CubeSceneReference; [SerializeField] LoadableSceneId m_SphereSceneReference; // Store references to the loaded scenes so you can unload them later. Scene m_CubeScene; Scene m_SphereScene; void Start() { // LoadSceneMode.Additive loads the new scene alongside the current scene. // Use LoadSceneMode.Single instead if you want to replace the current scene. AsyncOperation cubeLoad = SceneManager.LoadSceneAsync(m_CubeSceneReference, new LoadSceneParameters(LoadSceneMode.Additive)); // completed fires when the load finishes. Retrieve the Scene object at that // point so you can unload it later. The _ parameter is the completed AsyncOperation, which isn't needed here. cubeLoad.completed += _ => { m_CubeScene = SceneManager.GetSceneByLoadableSceneId(m_CubeSceneReference); }; StartCoroutine(WaitAndLoadAnotherScene(1.0f)); } // Loads a second scene additively after a delay. private IEnumerator WaitAndLoadAnotherScene(float delay) { yield return new WaitForSeconds(delay); AsyncOperation sphereLoad = SceneManager.LoadSceneAsync(m_SphereSceneReference, new LoadSceneParameters(LoadSceneMode.Additive)); sphereLoad.completed += _ => { m_SphereScene = SceneManager.GetSceneByLoadableSceneId(m_SphereSceneReference); }; } // Call in response to a game event, such as a button press. public void WhenSomeEventHappens() { // Check isLoaded before unloading: the scene might still be loading // when this method is called. if (m_CubeScene.isLoaded) SceneManager.UnloadSceneAsync(m_CubeScene); } // Unload both scenes when this MonoBehaviour is destroyed to free memory. void OnDestroy() { if (m_CubeScene.isLoaded) SceneManager.UnloadSceneAsync(m_CubeScene); if (m_SphereScene.isLoaded) SceneManager.UnloadSceneAsync(m_SphereScene); } }

LoadableSceneId usage examples

The following are examples of how to use
LoadableSceneId
in your project. You can use more than one of these patterns in the same build.

Transition between scenes

A scene can contain a MonoBehaviour that unloads the current scene and loads a different one when a condition is met. This pattern suits projects where only a single scene is active at a time, such as games that transition between levels or regions of a large 3D world.
The following example transitions to a target scene when a character enters a 2D trigger:
using UnityEngine; using UnityEngine.SceneManagement; [RequireComponent(typeof(Collider2D))] public class SceneTransition : MonoBehaviour { public Unity.Loading.LoadableSceneId TargetScene; private void OnTriggerEnter2D(Collider2D col) { if (TargetScene.IsValid) SceneManager.LoadSceneAsync(TargetScene, new LoadSceneParameters(LoadSceneMode.Single)); } }
With this pattern you don't need to maintain a separate list of scenes to build, unlike AssetBundles or Addressables, where you assign each scene to an AssetBundle or group. However, scene references are spread across your project instead of in a central root asset, which means it's difficult to understand how many scenes a build includes. An alternative is to centralize scenes in a root asset, as described in the following section.

Centralize scenes in a root asset

For projects with many scenes, a
ScriptableObject
-derived class that holds a list of
LoadableSceneId
fields provides a single, visible record of all scenes in the build. This makes it easier to understand which scenes are in your project and gives a central place to manage scene loading logic, rather than spreading references across many MonoBehaviour objects inside scenes.
Use
ContentLoadManager.GetRootAssets<T>
at runtime to retrieve the root asset from a registered content directory.
The following example defines a scene list with named fields for a main menu, a UI scene, and an array of levels:
public class CustomSceneList : ScriptableObject { public LoadableSceneId MainMenu; public LoadableSceneId UI; public LoadableSceneId[] Levels; // Include a single asset of this type in the root asset list. // Use this method to retrieve it in the Player or during Editor Play mode. static public CustomSceneList Get() { return ContentLoadManager.GetRootAssets<CustomSceneList>()[0]; } }

Find scenes from a content directory

You can build scenes into a separate content directory and allow code in the Player build to discover them at runtime. Register the content directory with
ContentLoadManager.RegisterContentDirectory
, retrieve the root asset with
ContentLoadManager.GetRootAssets<T>
, then load the scene with
SceneManager.LoadSceneAsync
.
The following example registers a content directory that contains a
CustomSceneList
root asset, like the one defined in the previous section, and loads a level scene from it:
public class LoadSceneFromRootAsset { // Reuses the CustomSceneList root asset defined in the previous example. public static IEnumerator LoadLevelScene(string contentDirectoryPath, Action<Scene> onSceneLoaded) { ContentLoadManager.RegisterContentDirectory(contentDirectoryPath); CustomSceneList root = ContentLoadManager.GetRootAssets<CustomSceneList>()[0]; LoadableSceneId sceneReference = root.Levels[0]; AsyncOperation op = SceneManager.LoadSceneAsync(sceneReference, new LoadSceneParameters(LoadSceneMode.Additive)); yield return op; Scene loadedScene = SceneManager.GetSceneByLoadableSceneId(sceneReference); onSceneLoaded?.Invoke(loadedScene); } }
重要
Avoid building the same scene into both the Player build and a content directory. This duplicates the scene and its dependencies in the build output, increasing build size. There's no public API for selecting which copy loads at runtime, so the result is unpredictable.

Additional resources