添加场景
验证环境
- 窗户
-
- 视窗 11
- 统一编辑器
-
- 2020.3.25f1
- 输入系统包
-
- 1.2.0
此提示的先决条件
作为此提示描述的前提,已预先进行了以下设置。
关于添加场景
Unity 允许您同时显示多个场景。 当您只想叠加场景或将绘图导出为其他纹理时,请使用它。
这次,我想解释一下场景的叠加显示,假设在游戏运行时游戏运行时,菜单屏幕显示在前景中。
显示多个场景时,应注意以下事项:
- 事件系统不得超过一个
- 音频侦听器不得超过一个
- 处理多台相机时要小心
准备场景
这次,我们将准备两个场景。 设 , SampleSceneParent
另外要显示的场景 SampleSceneChild
是 。
准备两个场景的方法和前面的技巧一样,请参考一下。
这一次,我们将创建以下布局。 如果单击父场景中的按钮,则除了添加子场景外,没有任何问题。
放置精灵是为了更容易 Canvas
理解稍后将看到的症状。
样本场景父级
样本场景儿童
显示多个场景时,对象的上下文取决于每个对象的“图层顺序”,而不考虑场景单位。
由于初始值均为 0,因此请将 no 和子画面设置为SampleSceneChild
Canvas
“1”。
不要忘记在构建设置中设置这两个场景。
处理场景
它在代码中的处理方式与切换场景相同。 这一次,它也是在单击按钮时处理的,但它被处理为添加而不是场景切换。
脚本文件的名称是任意的,但这里是 SceneAdd
.
脚本如下所示:
using UnityEngine;
using UnityEngine.SceneManagement; // 追加
public class SceneAdd : MonoBehaviour
{
<summary>ボタンをクリックしたときに呼ばれます。</summary>
public void OnClick()
{
// 指定したシーンを追加します
SceneManager.LoadScene("SampleSceneChild", LoadSceneMode.Additive);
}
}
切换场景时, LoadSceneMode
我设置为 , Single
但这次 Additive
是 。
这就是区别的全部。
保存脚本后SampleSceneParent
,将其附加到 。 EventSystem
在按钮上 OnClick
设置方法。
尝试运行游戏以查看其工作原理。 如果单击该按钮,您将看到子场景。
此外,如果您查看层次结构,您可以看到有两个场景。
但是,尽管已添加场景,但似乎未显示父场景的 Canvas 的内容。 相反,您可以看到父场景中的精灵根据图层的顺序显示在背面。
此外,如果您查看控制台,您可以看到日志不断输出。
内容有以下两点。
- 场景中有 2 个事件系统。 请确保场景中始终只有一个事件系统
- 场景中有 2 个音频侦听器。 请确保场景中始终只有一个音频侦听器。
当使用多个场景时,需要对应这两个点和相机。
修复事件系统错误
日志的内容如下。
场景中有 2 个事件系统。 请确保场景中始终只有一个事件系统
(场景中有两个事件系统。 确保场景中始终有一个事件系统)
如前所述,将事件系统组合成一个解决方案将解决问题。
SampleSceneParent
假定始终存在,SampleSceneChild
因此请在打开它时 EventSystem
将其删除。
当然,请注意,如果您自行运行,SampleSceneChild
按钮等 UI 将不起作用。
您可以看到,当您运行事件系统日志时,它已消失。
SampleSceneParent
此外,由于存在EventSystem
,因此可以激活子场景中的按钮。
修复音频侦听器错误
日志的内容如下。
场景中有 2 个音频侦听器。 请确保场景中始终只有一个音频侦听器。
(场景中有两个音频侦听器。 确保场景中始终只有一个音频侦听器。 )
Main Camera
如果您查看 的组件,您当然可以看到音频侦听器存在,因此 SampleSceneChild
您可以删除 中的音频侦听器。
它可以通过相机控制下一个项目来解决,因此我们将在那里处理它。
如果要保留相机,SampleSceneChild
将删除此音频侦听器。
更改相机以显示两个场景
至于添加子场景时只显示子场景画布的原因, 这是因为画布上设置了两个摄像机,即父场景和子场景,并且只显示一个摄像机。
解决方案是使用父场景的相机显示两个场景的画布。 该过程是在添加子场景后,将子场景画布上的摄像机替换为父场景的摄像机。
让我们创建一个脚本。 名称是任意的,但在这种情况下 ChildSceneCamera
是.
脚本如下所示: Canvas
这是附加到 的先决条件过程。
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ChildSceneCamera : MonoBehaviour
{
<summary>シーンに追加されたタイミングで処理されます。</summary>
void Awake()
{
// 親のシーンのキャンバスを取得
var parentScene = SceneManager.GetSceneByName("SampleSceneParent");
var parentCanvas = parentScene.GetRootGameObjects().First(obj => obj.GetComponent<Canvas>() != null).GetComponent<Canvas>();
// 子のシーンのキャンバスを取得
var childCanvas = GetComponent<Canvas>();
// 子のシーンのカメラを削除
Object.Destroy(childCanvas.worldCamera.gameObject);
// 子のシーンのキャンバスのカメラを親のシーンのカメラに置き換えます
childCanvas.worldCamera = parentCanvas.worldCamera;
}
}
Awake
该方法在对象首次存在于场景中时执行。 Start
在方法之前执行。
最好记住您经常使用它。
这一次,假设它将在添加子场景时执行。
<summary>シーンに追加されたタイミングで処理されます。</summary>
void Awake()
{
// 処理
}
获取父场景画布和子场景画布以替换摄像机。 有多种方法可以做到这一点,但这不是主要主题,所以你可以认为如果你暂时这样做,你可以得到它。
// 親のシーンのキャンバスを取得
var parentScene = SceneManager.GetSceneByName("SampleSceneParent");
var parentCanvas = parentScene.GetRootGameObjects().First(obj => obj.GetComponent<Canvas>() != null).GetComponent<Canvas>();
// 子のシーンのキャンバスを取得
var childCanvas = GetComponent<Canvas>();
首先销毁子场景的摄像机 Object.Destroy
。 即使它消失了,也没有问题,因为它可以被父母场景的相机覆盖。
从 检索删除目标 Canvas.worldCamera
。
只是因为此时场景设置了相同的摄像机,可以轻松获取。
如果你真的想删除它,你最好从场景中获取相机。
// 子のシーンのカメラを削除
Object.Destroy(childCanvas.worldCamera.gameObject);
最后,将子场景替换为父场景 Canvas.worldCamera
的摄像机。
// 子のシーンのキャンバスのカメラを親のシーンのカメラに置き換えます
childCanvas.worldCamera = parentCanvas.worldCamera;
保存脚本后SampleSceneChild
,将其附加到 。 Canvas
如果执行并添加子场景的结果如下图所示,则可以。 确保也没有日志。