了解Unity3d中的场景

时间:2014-01-04 04:20:00

标签: unity3d game-engine scene

我对Unity3d中的场景感到困惑,但我无法找到有关它们的任何资源。

  1. 什么时候应该使用场景?例如,在平台游戏中,每个级别都必须是不同的场景?主菜单会是一个场景吗?
  2. 可以叠加场景吗?
  3. 资源如何在场景之间起作用?它们是否与每个场景相关联,每次都必须重新加载。可以指定何时不再需要资产吗?
  4. 如何在场景之间的场景/界面之间发送数据? 我知道这是一个广泛的主题,但我不希望垃圾邮件有多个问题。

4 个答案:

答案 0 :(得分:58)

  

什么时候应该使用场景?例如,平台游戏中的每一个   水平必须是一个不同的场景?主菜单会是一个场景吗?

没有关于此的一般规则。从理论上讲,整个游戏可能只有一个场景。 如何组织场景完全取决于您,并且通常取决于您正在创建的游戏类型。

我认为使用场景至少要考虑3个功能:

  • 它们是所有预先实例化对象的逻辑容器,可能有助于将您的游戏划分为多个级别/部分。
  • 您可以在场景内GameObjectsComponents之间序列化交叉引用(如果GO A需要参考GO B,并且它们属于同一场景,引用可以序列化,您不再需要在运行时找到引用的对象)
  • 当您加载(不是以附加方式)另一个场景时,已经加载到内存中的资源会自动发布
  

可以叠加场景吗?

是的,您可以使用LoadAdditive。不幸的是,一旦将两个场景都加载到存储器中,就没有自动的方法来区分属于一个或另一个的对象。因此,如果您在第二级环境中加载添加剂,则由您来跟踪以前的环境,并在需要时明确销毁它。

  

资源如何在场景之间工作?他们是否依附于每一个   个别场景,每次都要重新加载。可以指定   何时不再需要资产?

默认情况下,一旦加载了新场景,场景的每个GameObject都将被销毁(除非您使用加法场景加载)。让GameObject在场景中生存的一种方法是使用DontDestroyOnLoad标记它。

如果您需要共享GameObject的特定“配置”,您可以将其存储为预制件,并在场景中引用它(但请记住,在场景中它曾经是预制实例,因此GO与{ {3}}初始序列化和非覆盖属性,但同一预制件的2个实例是不同的对象。)

  

如何在场景之间的场景/界面之间发送数据?

有几种方法,具体取决于您要共享的持久数据类型。

  • 对于特定的GameObject实例,请使用DontDestroyOnLoad使对象生效。
  • 如果您有一些不需要附加到特定GameObject的配置数据,您可以考虑在prefab内存储ScriptableObject并引用它。
  • 如果您的数据必须在不同的游戏会话中保留,您可以考虑将其存储到AssetDatabase

还有其他两种我不喜欢的方式,但只是引用它们:

  • 使用静态字段有时可以帮助您完成此操作,但从我的角度来看,它有几个问题
  • 从磁盘保存和加载(在某些情况下可能很有用,但通常是依赖于平台的方式,尤其是在不同的移动平台上,您可能会遇到一些问题)。

这是一个广泛的话题,我希望这个答案可以是一个相当不错的概述。

答案 1 :(得分:2)

  

什么时候应该使用场景?例如,在平台游戏中,每个级别都必须是不同的场景?主菜单会是一个场景吗?

没有关于游戏中需要有多少场景的规则。但是,场景允许您从逻辑上将游戏的其他部分与其余部分分开。您必须至少有一个场景。

通过主菜单,如果您指的是带有UI元素的画布,它将在场景中而不是场景本身。 Canvas只是另一个GameObject,我们大多用它来显示游戏菜单。我主要创建一个Canvas GameObject,将一个脚本名为" UIManager"并将DontDestroyOnLoad放在上面,所以我可以在所有场景中访问它。设为Singleton并确保不重复。

  

可以叠加场景吗?

是的,对于一次可以加载多少个场景没有限制。你计划覆盖场景的目的是什么?也许有一种比加载加载更好的方法。

  

资源如何在场景之间工作?它们是否与每个场景相关联,每次都必须重新加载。可以指定何时不再需要资产吗?

资产就是您在“项目”中看到的内容。层次结构。我认为你的意思是场景中的游戏对象,如果是,请将你的游戏对象想象成具有组件的实体(Entity-Component System)。场景中的所有实体在其父场景被销毁之前都会被销毁,直到明确声明不使用某个组件中的DontDestroyOnLoad(在统一的情况下为单行为)。被摧毁的人将被收集垃圾。

因此,如何加载(或重新加载)取决于您的实现,是否要再次实例化/销毁它们,或者将实例化的预制件放在cached object中并稍后从中检索。

  

如何在场景之间的场景/界面之间发送数据?

海森涵盖了我能想到的那些。只是为它添加一点,它还取决于你想要如何构建你的项目。因此,如果您有一个基础数据结构,例如按住Commands,您可以在项目的任何部分自由使用

答案 2 :(得分:0)

大多数游戏都会组织为每个级别(包括主菜单)都有场景,但这完全取决于您。 如果将数据保存在文本文件或二进制文件中,则可以将数据从一个场景用于另一个场景。有很多关于如何做到这一点的教程。我发现文档有很大帮助。 资产在项目中是通用的。 您不能叠加场景。

答案 3 :(得分:0)

<块引用>

什么时候应该使用场景?例如,在平台游戏中,每个关卡都必须是不同的场景吗?主菜单会是一个场景吗?

何时使用场景取决于您。如果您刚刚开始,我建议您为游戏的每个部分使用不同的场景。

<块引用>

可以叠加场景吗?

是的,使用 LoadSceneMode.Additive()。 (LoadAdditive() 已过时)

<块引用>

资产如何在场景之间工作?它们是否附加到每个单独的场景并且每次都必须重新加载。可以指定何时不再需要资产吗?

默认情况下,使用 SceneManager.LoadScene() 时会删除资产。但是,如果使用DontDestroyOnLoad(),则进入新场景时对象不会被破坏。如果您只想通过几个场景而不是所有场景保留一个对象,请使用带有一些布尔逻辑的 Destroy()

<块引用>

如何在场景之间/场景之间的接口之间发送数据?我知道这是一个广泛的主题,但我不想发送多个问题。

您可以通过使用前面提到的 DontDestroyOnLoad()、引用不同脚本上的数据、使用 ScriptableObjects、使用 JSON Serialization、使用 StreamWriter()、使用 {{3} 来通过场景发送数据} (不要用于重要信息),列表还在继续。我个人建议使用 ScriptableObjects 来提高其可访问性,使用 StreamWriter() 来提高其加密功能。