Version: 2020.3
创建、加载和保存场景
场景模板

Multi-Scene editing

多场景编辑允许同时在 Editor 中打开多个场景,并简化运行时场景管理。

在 Editor 中打开多个场景的功能允许创建大型流媒体世界,并在协作场景编辑时改进工作流程。

本页介绍以下内容:

  • Editor 中的多场景编辑集成
  • Editor 脚本和运行时脚本 API
  • 当前的已知问题

在 Editor 中

To open a new scene and add it to the current list of scenes in the Hierarchy, either select Open Scene Additive in the context menu for a scene asset, or drag one or more scenes from the Project window into the Hierarchy Window.

Open Scene Additive 会将所选场景资源添加到层级视图中显示的当前场景
Open Scene Additive 会将所选场景资源添加到层级视图中显示的当前场景

在 Editor 中打开多个场景时,每个场景的内容将在 Hierarchy 窗口中单独显示。每个场景的内容都显示在场景分隔栏下方,该分隔栏会显示场景的名称及其保存状态。

Hierarchy 窗口显示了同时打开的多个场景
Hierarchy 窗口显示了同时打开的多个场景

场景存在于层级视图中时,可加载卸载场景以显示或隐藏每个场景中包含的游戏对象。此操作与在 Hierarchy 窗口中添加删除场景的操作不同。

层级视图中的场景分隔栏可折叠场景内容,如果加载了大量场景,此功能有助于导航层级视图。

When working on multiple scenes, each scene that’s modified will need its changes saved, so it’s possible to have multiple unsaved scenes open at the same time. Scenes with unsaved changes will have an asterisk shown next to the name in the scene divider bar.

场景分隔栏中的星号表示此场景有未保存的更改
场景分隔栏中的星号表示此场景有未保存的更改

每个场景都可以通过分隔栏中的上下文菜单进行单独保存。从 File 菜单中选择“Save Scene”或按 Ctrl/Cmd + S 将保存对所有打开场景的更改。

场景分割栏中的上下文菜单允许对所选场景执行其他操作。

The Scene divider menu for loaded Scenes

Set Active Scene This allows you to specify which scene new Game Objects are created/instantiated in. There must always be one scene marked as the active scene
Save Scene Saves the changes to the selected scene only.
Save Scene As Saves the selected scene (along with any current modifications) as a new Scene asset.
Save All Saves changes to all scenes.
Unload Scene Unloads the scene, but keeps the scene in the Hierarchy window.
Remove Scene Unloads and removes the scene from the Hierarchy window.
Select Scene Asset Selects the scene’s asset in the Project window.
GameObject Provides a sub-menu allowing you to create GameObjects in the selected scene. The menu mirrors the creatable items available in Unity’s main GameObject menu. (shown below)
场景分割栏菜单中的 GameObject 子菜单
场景分割栏菜单中的 GameObject 子菜单

The Scene divider menu for unloaded Scenes:

Load Scene Loads the scene’s contents
Remove Scene Remove the scene from the Hierarchy window.
Select Scene Asset Selects the scene’s asset in the Project window.

烘焙包含多个场景的光照贴图

To bake Lightmap data for multiple scenes at once, you should open the scenes that you want to bake, disable “Auto” mode in the Lighting Window, and click the Build button to build the lighting.

The input to the lighting calculations is the static geometry and lights from all scenes. Therefore shadows and GI light bounces will work across all scenes. However, the lightmaps and Enlighten Realtime Global Illumination data are separated out into data that’s loaded / unloaded separately for each scene. The lightmaps and Enlighten Realtime Global Illumination data atlases are split between scenes. This means lightmaps between scenes are never shared and they can be unloaded safely when unloading a scene. Lightprobe data is currently always shared and all lightprobes for all scenes baked together are loaded at the same time.

或者,可在 Editor 脚本中使用 Lightmapping.BakeMultipleScenes 函数自动为多个场景构建光照贴图。

Baking NavMesh data with multiple Scenes

To bake NavMesh data for multiple scenes at once, you should open the scenes that you want to bake, and click the Bake button in the Navigation Window. The NavMesh data will be baked into a single asset, shared by all loaded scenes. The data is saved into the folder matching the name of the current active scene (for example ActiveSceneName/NavMesh.asset). All loaded scenes will share this NavMesh asset. After baking the NavMesh, the scenes affected should be saved to make the scene-to-NavMesh reference persistent.

Alternatively, you can automate building NavMesh data for multiple scenes by using the NavMeshBuilder.BuildNavMeshForMultipleScenes function in an editor script.

烘焙包含多个场景的遮挡剔除数据

To bake occlusion culling data for multiple Scenes at once, open the Scenes that you want to bake, open the Occlusion Culling window (menu: Window > Rendering > Occlusion Culling) and click the Bake button. The occlusion culling data is saved into an asset called OcclusionCullingData.asset in a folder matching the name of the current active scene. For example Assets/ActiveSceneName/OcclusionCullingData.asset. A reference to the data is added in each open Scene. After baking the occlusion culling data, save the Scenes affected to make the Scene-to-occlusion-data reference persistent.

每当以累加方式加载场景时,如果该场景具有与活动场景相同的遮挡数据引用,则会从遮挡数据中初始化该场景的静态渲染器和入口剔除信息。此后,遮挡剔除系统认为所有静态渲染器和入口都已烘焙到单个场景中。

播放模式

In Play mode, with multiple scenes in the Hierarchy, an additional scene will appear called DontDestroyOnLoad.

Prior to Unity 5.3, any objects you would instantiate in Playmode marked as “DontDestroyOnLoad” would still appear in the hierarchy. These objects aren’t considered part of any scene but for Unity to still display the objects, and for you to inspect them, these objects are now shown as part of the special DontDestroyOnLoad scene.

You don’t have access to the DontDestroyOnLoad scene and it’s not available at runtime.

特定于场景的设置

许多设置是特定于每个场景的。如下:

  • RenderSettings 和 LightmapSettings(均位于 Lighting 窗口中)
  • 导航网格设置
  • 遮挡剔除窗口中的场景设置

具体工作原理是每个场景将管理自己的设置,只有与该场景相关的设置才会保存到场景文件中。

If you have multiple scenes open, the settings that are used for rendering and NavMesh are the ones from the active scene. This means that if you want to change the settings of a scene, you must either open only one scene and change the settings, or make the scene in question the active scene and change the settings.

如果在 Editor 中或在运行时切换活动场景,则会应用新场景中的所有设置并替换所有先前的设置。

脚本

Editor scripting

对于 Editor 脚本,我们提供了一个 Scene 结构EditorSceneManager API 以及一个 SceneSetup 实用程序类。

Scene 结构在 Editor 中和运行时都可用,并包含一些与场景本身相关的只读属性,例如其名称和资源路径。

The EditorSceneManager class is only available in the editor. It’s derived from SceneManager and has a number of functions that allow you to implement all the Multi Scene Editing features described above via editor scripting.

SceneSetup 类是一个小实用程序类,用于存储有关当前层级视图中的场景的信息。

The Undo and PrefabUtility classes have been extended to support multiple scenes. You can now instantiate a Prefab in a given scene using PrefabUtility.InstantiatePrefab, and you can move objects to the root of a scene in an un-doable manner using Undo.MoveGameObjectToScene

Note: To use Undo.MoveGameObjectToScene, you must make sure the GameObject is already at the root of the scene it’s currently in.

运行时脚本

对于运行时脚本,可在 SceneManager 类中找到用于处理多个场景的函数(如 LoadSceneUnloadScene)。

注意

在 File 菜单中,Save Scene As 将仅保存活动场景。Save Scene 将保存所有已修改的场景,并会提示命名无标题场景(如果存在)。

通过 Project 窗口的 Create 菜单创建新的场景资源
通过 Project 窗口的 Create 菜单创建新的场景资源

Tips and tricks

It’s possible to add a scene to the hierarchy while keeping it its unloaded state by holding Alt while dragging. This gives you the option to load the scene later, when desired.

可使用 Project 窗口中的 Create 菜单创建新场景。新场景将包含游戏对象的默认设置。

为避免每次重新启动 Unity 时都必须设置层级视图,或为了方便存储不同的设置,可使用 EditorSceneManager.GetSceneManagerSetup 获取一个描述当前设置的 SceneSetup 对象列表。然后,可将这些对象序列化为 ScriptableObject 或其他对象以及可能要存储的有关场景设置的所有其他信息。要恢复层级视图,只需重新创建 SceneSetup 列表并使用 EditorSceneManager.RestoreSceneManagerSetup

若要在运行时获取加载的场景列表,只需使用 GetSceneAt 获取 sceneCount 并遍历这些场景。

可通过 GameObject.scene 获取游戏对象所属的场景,并可使用 SceneManager.MoveGameObjectToScene 将游戏对象移动到场景的根目录。

It’s recommended to avoid using DontDestroyOnLoad to persist manager GameObjects that you want to survive across scene loads. Instead, create a manager scene that has all your managers and use SceneManager.LoadScene(<path>, LoadSceneMode.Additive) and SceneManager.UnloadScene to manage your game progress.

已知问题

  • Cross-Scene references aren’t supported, and are prevented in Edit mode. In Play mode they’re allowed, because Scenes can’t be saved.
创建、加载和保存场景
场景模板