介绍

在以前的教程中,所有内容都围绕节点的概念展开。场景是节点的集合。一旦进入场景树,他们就变得活跃起来。

主循环

Godot内部工作的方式如下。有 OS类,这是在开始时运行的唯一实例。之后,将加载所有驱动程序,服务器,脚本语言,场景系统等。

初始化完成后,需要为OS提供MainLoop 才能运行。至此,所有这些工作都在内部起作用(如果您有兴趣查看内部工作原理,则可以在源代码中检查main / main.cpp文件)。

用户程序或游戏在MainLoop中启动。此类具有一些方法,用于初始化,空闲(帧同步回调),固定(物理同步回调)和输入。同样,这是低级的,并且在Godot中进行游戏时,很少编写自己的MainLoop是有意义的。

场景树

解释Godot的工作方式的一种方法是,它是基于低级中间件的高级游戏引擎。

场景系统是游戏引擎,而OS和服务器是底层API。

场景系统为OS提供了自己的主循环 SceneTree。在运行场景时会自动创建实例并进行设置,而无需执行任何其他工作。

重要的是要知道此类的存在,因为它有一些重要的用途:

  • 它包含根视口,当场景首次打开以成为场景树的一部分时,该场景将作为子级添加到该场景(下一个更多内容)。
  • 它包含有关组的信息,并具有调用组中所有节点或获取它们列表的方法。
  • 它包含一些全局状态功能,例如设置暂停模式或退出过程。

当节点是场景树的一部分时, 可以通过调用Node.get_tree()获得SceneTree单例 。

根视口

视口 始终位于场景的顶部。在一个节点上,可以通过两种不同的方式获得它:

get_tree().get_root() # Access via scene main loop.
get_node("/root") # Access via absolute path.

该节点包含主视口。 默认情况下,将在视口中绘制任何视口的子对象 ,因此所有节点的顶部始终始终是此类型的节点是有意义的,否则将看不到任何内容。

尽管可以在场景中创建其他视口(用于分屏效果等),但该视口是用户从未创建过的唯一视口。它是在SceneTree内部自动创建的。

场景树

当节点直接或间接连接到根视口时,它成为场景树的一部分。

这意味着,如之前教程中所述,它将获得 _enter_tree() 和 _ready() 回调(以及 _exit_tree())

../../_images/activescene.png

当节点进入场景树时,它们会变得活跃。他们可以访问处理所需的一切、获取输入、显示 2D 和 3D 视觉效果、接收和发送通知、播放声音等。当他们从场景树中移除时 ,他们将失去这些能力。

树顺序

Godot 中的大多数节点操作,例如绘制 2D、处理或获取通知,都是按树顺序完成的。这意味着在树顺序中排名较低的父节点和兄弟节点将在当前节点之前得到通知。

../../_images/toptobottom.png

通过进入场景树“变得活跃”

  1. 场景从磁盘加载或通过脚本创建。
  2. 该场景的根节点(只有一个根,还记得吗?)被添加为“根”视口(来自 SceneTree)的子节点,或者添加到它的任何子节点或孙节点。
  3. 新添加场景的每个节点,都会按照从上到下的顺序收到“enter_tree”通知(GDScript 中的 _enter_tree() 回调)。
  4. 当一个节点及其所有子节点都在活动场景中时,为了方便起见,提供了一个额外的通知,“就绪”(GDScript 中的 _ready() 回调)。
  5. 当一个场景(或其中的一部分)被移除时,它们会以自下而上的顺序收到“退出场景”通知(GDScript 中的 _exit_tree() 回调)

改变当前场景

加载场景后,通常需要将此场景更改为另一个场景。这样做的简单方法是使用 SceneTree.change_scene() 函数:

func _my_level_was_completed():
    get_tree().change_scene("res://levels/level2.tscn")

除了使用文件路径,还可以使用等效函数SceneTree.change_scene_to(PackedScene scene)使用现成的 PackedScene资源 :

var next_scene = preload("res://levels/level2.tscn")

func _my_level_was_completed():
    get_tree().change_scene_to(next_scene)

这些是切换场景的快速且有用的方法,但有一个缺点,即游戏将在加载并运行新场景之前停止。在您的游戏开发的某个阶段,创建带有进度条、动画指示器或线程(背景)加载的适当加载屏幕可能更可取。这必须使用自动加载(见下一章)和后台加载手动完成。