添加场景

更新页 :
页面创建日期 :

验证环境

窗户
  • 视窗 11
统一编辑器
  • 2020.3.25f1
输入系统包
  • 1.2.0

此提示的先决条件

作为此提示描述的前提,已预先进行了以下设置。

关于添加场景

Unity 允许您同时显示多个场景。 当您只想叠加场景或将绘图导出为其他纹理时,请使用它。

这次,我想解释一下场景的叠加显示,假设在游戏运行时游戏运行时,菜单屏幕显示在前景中。

显示多个场景时,应注意以下事项:

  • 事件系统不得超过一个
  • 音频侦听器不得超过一个
  • 处理多台相机时要小心

准备场景

这次,我们将准备两个场景。 设 , SampleSceneParent另外要显示的场景 SampleSceneChild 是 。 准备两个场景的方法和前面的技巧一样,请参考一下。

这一次,我们将创建以下布局。 如果单击父场景中的按钮,则除了添加子场景外,没有任何问题。 放置精灵是为了更容易 Canvas 理解稍后将看到的症状。

样本场景父级

样本场景儿童

显示多个场景时,对象的上下文取决于每个对象的“图层顺序”,而不考虑场景单位。 由于初始值均为 0,因此请将 no 和子画面设置为SampleSceneChildCanvas“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

如果执行并添加子场景的结果如下图所示,则可以。 确保也没有日志。