跳转至

1.3 场景面板与多场景管理

节点、场景和场景树

节点

节点是创建内容的基本构成。引擎里有很多种节点,每个节点类型可以执行特定的功能,例如有的可以播放声音,有的可以显示图像,有的显示3D模型等等。任何给定的节点都具有如下统一属性: - 具备节点名称; - 可以编辑各种属性; - 可以持有子节点; - 可以作为子节点添加到其他节点; - 可以接收回调方法; - 可以扩展出更多功能;

我们可以点击 + 来创建一个新的节点: imageCover

也可以在一个节点上右键点击创建一个新的节点: imageCover

我们可以通过顶部的快捷工具栏以及右键菜单来对节点的属性以及显示进行操作。 例如:我们可以点击工具栏右上角图标展开折叠场景树中的节点。 我们可以选中节点右键选择展开折叠当前节点。 imageCover

温馨提示

节点与节点之间存在父子关系,如上图我们在一个节点上创建一个新的节点,那么新创建的节点是原节点的子节点,原有的那个节点是新节点的父节点,二者是父子关系。父节点的某些属性会影响到子节点,例如在Spatial类型的节点上创建一个新的节点,那么该节点的初始位置会在其父节点的位置。再例如父节点的隐藏会导致其子节点跟着隐藏

场景

通过在一个节点上添加一个子节点的操作,我们可以将节点与节点之间排成树状结构。在若干次的节点组织后,我们可以得到一个场景。场景文件后缀为.scene。该场景包含了一个树状的节点集合,如下图所示: imageCover

温馨提示

场景根节点是指场景中最基础的节点,在上述场景中,FirstPerson是该场景的根节点。

一个项目中可以有很多个场景,在运行时,我们需要定义一个主场景,主场景有且仅有一个。主场景是项目运行时的那个场景。我们可以在 编辑 -> 项目设置 中设置主场景。 imageCover

场景树

场景树是引擎为底层提供的主循环。在项目运行时会自动实例化并设置,不需要任何额外的操作。场景树有很重要的作用:

  • 包含一个根视图。当一个场景添加到场景树中时,会把这个场景添加到根视图中作为其子级;

  • 包含编组信息,具有组相关的方法;

  • 包含一些全局状态功能。

运行时可以查看远程的节点树,如下图所示: imageCover

场景树搜索

场景树提供了搜索筛选功能,在图中位置输入节点名称,即可显示出符合筛选条件的节点 imageCover 双击筛选后的节点,可聚焦到选中节点上。

场景树的筛选支持子场景节点的筛选 比如搜索上图**平面**子场景中的节点**静态刚体**,搜索结果如下: imageCover 图中 1 处即为符合筛选条件的节点,该节点位于**平面**子场景里。双击即可聚焦。 图中 2 处表明是子场景的根节点,点击这个图标即可进入子场景。 **平面**子场景的场景树如下: imageCover

节点操作

实例化子场景

一个项目中可以有多个场景,实例化子场景用来组织项目中的场景。例如,我们有一个房子的场景,和一个小区场景,我们可以在小区场景中实例化多个房子的场景,并排布实例化的节点,这样小区场景中就会有很多的房子。 实例化一个子场景有两种方式,如下所示: imageCover 接下来选择要实例化的场景: imageCover

温馨提示

可以实例化的除了.scene文件还有一些可以当成场景的文件,比如.fbx和.gltf等。

注意

一个场景被实例化为多个节点,如果修改这个原场景,实例化后的节点也会被修改。此外,对于实例化后的节点,修改其中的一个节点,不会改变原场景。

实例化子场景便利我们做项目:

  • 可以细分场景,便于管理;

  • 同时管理编辑多个节点实例;

  • 组织、嵌入复杂项目和UI;

对于实例化子场景之后生成的节点,右击该节点会多出如下选项:

imageCover

子节点可编辑 功能可以将该实例化的节点展开,能够看到并编辑该场景下的子节点。展开的子节点颜色会比较淡一点。在这里修改展开的子节点的属性,只会在该场景中起作用。其他未修改的属性相当于原场景的引用。修改原场景中的属性,如果实例化的节点的子节点并没有被修改则会受到原场景的影响。 imageCover

加载为占位符 功能主要适用于大场景。该选项打开后,运行项目时该场景节点会被一个占位符取代,只有调用replace_by_instance方法后才会加载实际的场景。

使用本地功能 与子节点可编辑功能类似,但是有本质上的区别。其展开的子节点颜色正常。使用本地会将原场景中的节点树复制一份到新的场景中,而不是引用。 imageCover

在编辑器中打开 功能是指打开这个场景文件。我们可以看到场景实例化来的节点旁边会有一个类似放映的图标,点击可以打开原场景文件。这两个的功能是一致的。

从场景中合并

右击节点,会出现一个 从场景中合并 的选项,点击它可以选中其他场景文件中一些节点,点击确认后复制一份到当前节点的子节点位置。操作如下图:

imageCover

点击从场景中合并

imageCover

选择场景文件

imageCover

选择要合并的节点

imageCover

结果如图,两个被选中的节点出现在了当前场景中

将分支保存为场景

将分支保存为场景 功能与实例化子场景互为相反操作。如果场景树太复杂,可以使用此功能将部分节点树拆分出去。此外,如果有部分子树可以独立出来供复用的话,可以使用该功能。具体操作可以参考下图:

imageCover

imageCover

imageCover

信号和Groups

选中某个节点之后,点击场景旁边的节点选项,我们可以看到两大块内容,一个是信号,一个是Groups。

imageCover

信号

节点会有一些引擎做好的信号,我们可以在信号触发后实现某些功能,即信号的回调函数。这里我们点击节点A,右键它的某个信号,点击连接信号,选择一个具有脚本的节点B,编辑连接方法,点击确认,就会在节点B的脚本中看到刚刚定义的接收方法。如下列图集所示:

imageCover

imageCover

imageCover

上述操作完成后,当节点A触发我们选择的信号后会执行节点B脚本里的对应回调方法。

当不想在信号触发后调用之前的方法时,可以点击取消连接,这样信号触发后不会再调用之前设置的回调方法。

Groups

Groups 是基于场景树的节点组集合。将某些节点添加到相同组名的group里,就可以通过节点树获取到该组中的所有节点。它提供了一种节点组织方式。

可以按照下图操作将节点添加到指定组:

imageCover

当想将节点移出某个组时,可以点击组名右侧的删除标识:

imageCover

温馨提示

一个节点可以同时加入到多个group中。

多场景管理

三种新建场景模板的区别和用途

引擎提供了3中新建场景模板,分别是3D场景,2D场景和空场景,如下图所示: imageCover

3D场景 是引擎预设的一个场景,在这个场景中有4个节点,分别是 Spatial 节点, MainCamera 节点, Plane 节点和 DirectionalLight 节点。 Spatial 节点是场景的根节点。 MainCamera 节点是一个相机类型的节点,引擎给该节点添加了一个脚本,用来实现相机的自由移动。 Plane 是一个MeshInstance类型的节点,即下方的棋盘格。 DirectionalLight 节点是一个平行光节点,给场景以光照。该场景提供了一些基础的节点,你可以基于该场景继续创作。

imageCover

2D场景 是用来制作UI的场景。引擎预设了两个节点,分别是 Control 和 Button 节点。其他的2D UI节点需要项目开发者自己制作。 imageCover

空场景 是一个3D的空场景。这个场景中只有一个 Spatial 节点。你可以在该场景下尽情创作。 imageCover

场景拆分原则

基本原则

在做项目中,组织场景要考虑的最重要的一件事是保持具有焦点的,单一用途的场景及其脚本,并与项目中的其它部分降低耦合。这样可以使每个对象尽量的小,并提高其可复用性。尽量设计低依赖甚至没有依赖的场景。

脚本功能管理

一个场景中,根节点应当具有与外部通讯所需的全部接口。最好的访问方式是通过实例化后的场景节点上暴露出的接口访问,而不必去关注其内部的节点组成和脚本。每一个场景,最好是由根节点来协调各子节点之间的通信和引用,兄弟节点之间应该只知道它们自己的层次结构,而不必了解其兄弟的存在。

资源管理

此外,项目里各类场景的存放位置需要注意,一类场景或者资源最好放在同个目录下,按照各个场景的职能组成树状结构保存。

多人开发如何进行项目管理

要开发一个大型项目,必然是需要一个协作的团队。团队中的人应各司其职,通力协作,才能最有效率的做好一个项目。

管理工具

在多人开发中,需要一个管理的工具。可以使用git或者svn。通过这类工具,能够方便的查阅历史代码,实现协同开发。

需求,设计与开发

接下来,需要一个主程,负责整个项目的统筹。主程需要设计整个项目的架构,将需求转化为具体的功能设计。某块功能要实现什么样的功能,要提供哪些接口,都需要设计好。最好是提供一份明确的需求文档。 此外,开发文档和主要代码的注释是要输出的。负责功能模块的开发者需要针对需求文档输出一份描述具体实现的文档,并与相关同事评审讨论。 敲定下方案后,按照方案进行内容开发。若遇到未预料的错误或者困难,及时沟通是很好的习惯。

测试与总结

功能开发完成后,需要进行自测试,修复bug或者优化代码。处理结束后,输出开发文档,供其他人阅读。 最后,分享和总结可以绕过很多弯路,写的好的地方或者遇到的问题都可以分享给其他开发者。可以固定频率进行分享,例如一周一次。