我对Unity3d中的场景感到困惑,但我无法找到有关它们的任何资源。
答案 0 :(得分:58)
什么时候应该使用场景?例如,平台游戏中的每一个 水平必须是一个不同的场景?主菜单会是一个场景吗?
没有关于此的一般规则。从理论上讲,整个游戏可能只有一个场景。 如何组织场景完全取决于您,并且通常取决于您正在创建的游戏类型。
我认为使用场景至少要考虑3个功能:
GameObjects
和Components
之间序列化交叉引用(如果GO A需要参考GO B,并且它们属于同一场景,引用可以序列化,您不再需要在运行时找到引用的对象)可以叠加场景吗?
是的,您可以使用LoadAdditive。不幸的是,一旦将两个场景都加载到存储器中,就没有自动的方法来区分属于一个或另一个的对象。因此,如果您在第二级环境中加载添加剂,则由您来跟踪以前的环境,并在需要时明确销毁它。
资源如何在场景之间工作?他们是否依附于每一个 个别场景,每次都要重新加载。可以指定 何时不再需要资产?
默认情况下,一旦加载了新场景,场景的每个GameObject
都将被销毁(除非您使用加法场景加载)。让GameObject
在场景中生存的一种方法是使用DontDestroyOnLoad标记它。
如果您需要共享GameObject的特定“配置”,您可以将其存储为预制件,并在场景中引用它(但请记住,在场景中它曾经是预制实例,因此GO与{ {3}}初始序列化和非覆盖属性,但同一预制件的2个实例是不同的对象。)
如何在场景之间的场景/界面之间发送数据?
有几种方法,具体取决于您要共享的持久数据类型。
GameObject
实例,请使用DontDestroyOnLoad
使对象生效。GameObject
的配置数据,您可以考虑在prefab内存储ScriptableObject并引用它。 还有其他两种我不喜欢的方式,但只是引用它们:
这是一个广泛的话题,我希望这个答案可以是一个相当不错的概述。
答案 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() 来提高其加密功能。