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.gd
、quit_button.gd
等等。
通过使用信号,我们只需要一个 Button
脚本(实际上是 built in 到 Godot!)。此按钮仅负责在单击时发出信号,然后我们可以将其连接到任意操作。
考虑信号时,您可以定义小的、独立的节点,而无需了解外部世界。这些节点可以放在场景树中的任何位置并根据需要连接起来,让您可以快速构建场景!
I need a way to solve the signal problem as well
我希望在阅读本文后您会发现信号不是需要解决的问题。耦合是问题,信号是解决问题的工具。
我一直在尝试以这种方式从单例脚本发送信号:
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.gd
、quit_button.gd
等等。
通过使用信号,我们只需要一个 Button
脚本(实际上是 built in 到 Godot!)。此按钮仅负责在单击时发出信号,然后我们可以将其连接到任意操作。
考虑信号时,您可以定义小的、独立的节点,而无需了解外部世界。这些节点可以放在场景树中的任何位置并根据需要连接起来,让您可以快速构建场景!
I need a way to solve the signal problem as well
我希望在阅读本文后您会发现信号不是需要解决的问题。耦合是问题,信号是解决问题的工具。