Godot 信号 "Emitted" 但不是 "Received"

Godot Signal "Emitted" but not "Received"

我一直在尝试以这种方式从单例脚本发送信号:

if(Input.is_action_just_pressed("ui_select")):
    emit_signal("update_inventory")
    #More Code underneath - 

我已经在显示我的库存物品的 UI 元素上声明了信号。像这样 -

signal update_inventory

以及通过编辑器连接到它的函数的声明 -

func _on_Inventory_update_inventory():
    #My code here

我试图理解一个类似的问题(我这么认为?)here。我完全听不懂。我看到有人在里面说——信号是物体的局部信号。他们,真的吗?如果是,为什么不正常调用该函数?信号点会被打败,不是吗?

我也需要一种方法来解决信号问题。也许我没有正确配置它。我哪里错了?

如果需要,我非常乐意提供更多信息。

Signals are local to an object. Are they, really?

是的。如果您在节点 A 中定义信号,则该信号必须从节点 A 发出。通常你会从 A 本身调用 emit_signal,因为信号是一个 Node 通知其他人发生了一些有趣的事情的一种方式。

如果出于某种原因你 想要从另一个 Node 发出信号,你需要获得对包含信号的 Node 的引用不知何故:

$Path/To/A.emit_signal("something_happened")

这是一件好事,如果信号总是全局的,它们就不会那么有用了。考虑 Button.pressed 信号。在有很多按钮的场景中,我们必须具体哪个按钮被按下了。是 "Start game" 按钮还是 "Quit Game" 按钮?仅从该场景中的任何节点调用 emit_signal("pressed") 的能力是不明确的。

但是,某些信号可能在本质上是 "global",例如 game_over。为此,您可以使用 "Event Bus"。听起来您可能正在尝试这样做,但您应该在 内部 单例中定义您的信号,如下所示:

# Events.gd (singleton)
signal game_started
signal game_over

然后各个节点可以选择从树中的任何位置侦听或发出这些信号。例如:

Events.emit_signal("game_started")

# in another node:
Events.connect("game_started", self, "start_music")

这通常被称为 publish-subscribe 模式。

why not call the function normally?

调用函数通常需要"sending"节点对"receiving"节点有特定的了解,这增加了节点之间的coupling。更紧密的耦合意味着更少的灵活性,这意味着更慢的游戏开发!

考虑我们的 UI 示例。如果按钮负责在单击时直接调用操作,则每个按钮都需要自定义代码来调用特定操作。我们有 start_button.gdquit_button.gd 等等。

通过使用信号,我们只需要一个 Button 脚本(实际上是 built in 到 Godot!)。此按钮仅负责在单击时发出信号,然后我们可以将其连接到任意操作。

考虑信号时,您可以定义小的、独立的节点,而无需了解外部世界。这些节点可以放在场景树中的任何位置并根据需要连接起来,让您可以快速构建场景!

I need a way to solve the signal problem as well

我希望在阅读本文后您会发现信号不是需要解决的问题。耦合是问题,信号是解决问题的工具。