如何在场景启动时推迟自定义动作?

How to defer custom action in scene startup?

我想访问场景的根节点,但即使在其 _ready() 生命周期方法中,我也收到运行时错误,告知父节点正忙:

extends Node2D

func _ready():
    self.get_tree().get_root().add_child(preload("res://MainMenu.tscn").instance())
    # This works:
    # self.get_tree().change_scene("res://MainMenu.tscn")

我现在的剧本只是暂时改变场景。我知道我可以使用这个 [object NodeTree].change_scene() 方法或 root_node.call_deferred(),但我希望能够观察到场景何时完全初始化,所以我可以自由使用它的节点树。

Nodeready 信号对你有用吗?即 yield(get_tree().get_root(), "ready")

_ready运行s的时候,父节点还没有准备好(更不用说场景根了)。 Godot 还没有完成将子节点添加到父节点的例程。事实上,它只是添加了你的当前节点,你当前节点的子节点,并且在你当前节点上 运行ning _ready。在它为你的当前节点和它的兄弟节点完成之后,它将在你的父节点上 运行 _ready ,依此类推,直到它到达场景根......然后它就准备好了。

Lightning_A 是正确的,在操作根之前插入 yield(get_tree().get_root(), "ready") 将起作用。 yield 将停止执行并安排它在给定信号后继续执行。本例中的 ready 信号。 _ready 完成后发生。

您将如何使用它:

func _ready():
    yield(get_tree().get_root(), "ready")
    get_tree().get_root().add_child(preload("res://MainMenu.tscn").instance())

另一种常见的解决方案是插入 yield(get_tree(), "idle_frame")。信号 idle_frame 发生在 Godot 调用 _process:

之前
func _ready():
    yield(get_tree(), "idle_frame")
    get_tree().get_root().add_child(preload("res://MainMenu.tscn").instance())