tutorial_scene_main_loop - seraph526/godot-se GitHub Wiki

场景主循环 (SceneMainLoop)

介绍(Introduction)

教程内容开始变得有些抽象了,但不用惊慌,因为它们并没有有多难。 在之前的教程中,所有的内容都是围绕Nodes的,场景是由它们组成的,当其进入场景时会被激活。

这值得我们更进一步。事实上,场景系统不是Godot的核心组件,因为,可以跳过它,写一个脚本(或C++代码),直接和Servers对话。但是,按照那种方法有很多工作要做,并且这一功能是预留做其他用途的。

主循环 (MainLoop)

Godot内在的工作原理如接下来所述。有个唯一的OS类在开始时被创建。然后,所有的驱动(drivers),服务(servers),脚本语言(scripting languages),场景系统(scene system)等等被加载。 初始化完成后,OS可以提供给MainLoop运行。到此,所有的工作都是内部工作(如果你对内部工作原理很感兴趣,可以查看main/main.cpp文件源码)

用户编程,或游戏,开始都是在主循环中。这个类有一些方法,如initialization, idle (frame-syncronized callback), fixed (physics-synchronized callback), 和 input。再次强调,在Godot中制作游戏时,这是真正的底层,编写你自己的MainLoop没有任何作用。

场景主循环 (SceneMainLoop)

一个解释Godot如何工作的说法是它是基于底层中间件的高级游戏引擎。 场景系统就是游戏引擎,相对的OS和servers是底层API。

在任何情况下,场景系统都会给OS提供它自己的主循环SceneMainLoop。 这是在运行场景时自动初始化和设置的,不需要做额外的工作。

知道这个类的存在很重要,因为它有一些很重要的用途: *它包括rootViewport,当场景第一次运行时,被填加为它的一个子节点,成为激活的场景的一部分(之后更多) *包含组信息,包含调用一个组中所有节点的方法,或得到一个相应的列表。 *包含一些全局状态函数,如设置pause模式,或退出进程。

当节点是激活场景的一部分时, SceneMainLoop可以通过简单的调用Node.get_scene()得到。

根视图 (Root Viewport)

根视图Viewport是场景的最顶级,有两种方法可以从节点调用它:

    get_scene().get_root() # access via scenemainloop
    get_node("/root") # access via absolute path

节点包含主视图,或其他任何Viewport的子节点默认都是在其内部绘制的,所以,让所有节点的最顶级是此节点类型还是有意义的,否则什么都不会看到。

在场景中可以创建其他的viewports(如分屏效果等),这是唯一一个从来不用用户创建的节点,它在SceneMainLoop内部被自动创建。

激活场景 (Active Scene)

当节点被直接或间接连接到根视图(root viewport),它就成为了激活场景的一部分。 也就是说,如之前教程讲的,会触发_enter_scene() 和 _ready()回调(当然还有_exit_scene())。

节点被激活后(在场景中),它们可以访问任何要处理的内容,获取input,显示2D和3D,通知,播放声音,组等等。当其从场景中移除后,不会获取任何东西。

树序列 (Tree Order)

Godot中的大部分节点操作,如绘制2D,处理或获取消息都是通过树序列完成的。就是说父节点和兄弟节点的排序靠前的较当前节点先得到消息。

"成为激活状态"细节

  1. 场景是从加载的或由脚本创建。
  2. 场景的根节点(只有一个根节点,记得么?)要么作为"root"Viewport的子节点(从 SceneMainLoop),要么是任意子节或孙节点被填加。
  3. 每个被新填加到场景的节点,都会按照从上到下的顺序接收"enter_scene"事件(GDScript中的_enter_scene()回调)。
  4. 一个特别的消息,"ready"(GDScript中的_ready()回调)可以很方便的知道一个节点和它的全部子节点已经被加载到当前激活场景中。
  5. 当场景(或部分场景)被移除,它们会按从上到下的顺序接收"exit scene"消息(GDScript中的_exit_scene()回调)。