nathanhoad / godot_dialogue_manager

A powerful nonlinear dialogue system for Godot
MIT License
2.09k stars 163 forks source link

Signal Scope? #360

Closed Runkli closed 11 months ago

Runkli commented 11 months ago

Describe the bug When trying to emit a signal that's not in the top most level, it is not picked up. I have a signal inside one of my Nodes that I would like to call by name, however, it seems that unless the signal is stated in the top most node, it is not picked up when emitted. Is there a way to "expose" local node signals to the global scope?

Affected version

To Reproduce Steps to reproduce the behavior:

Place a signal in a node script that is not the top most node. Try to emit that signal and see if it is being picked up.

When I launch a scene A only, with the signal in the scene A's script, it is picked up. However, when I launch the scene A as a child of scene B, and try to emit the same signal, it is not picked up.

Expected behavior All signals are equal, or there is a way to specify a global signal

Screenshots If applicable, add screenshots to help explain your problem. Try to include as much detail as possible. Set up where signal is picked up: image Inside of "Outside" script. image

Set up where signal is not picked up: Main Node: image

World, Outside are separate levels. When I replace World with Outside, and try to call the same signal, it is not picked up.

I hope this is clear, let me know if i can provide more details

Runkli commented 11 months ago

Maybe one solution would be to have a reference to the local node in the top node, and to call the signal through the reference in the top node?

Selenyhr commented 11 months ago

I'm having a bit of trouble seeing how you are using Dialogue Manager with the given example, and it seems like more general Godot behavior on how signals work.

This said, signals in Godot are not emitted through a global bus. When a signal is emitted, only objects that connected the specific emitting instance will receive the signal.

So in your case, you would need to connect the signal from your World node before you can attempt processing it. You can connect signals through the editor, or by using the drop_pot.connect() method. There is a great official tutorial on how to do this.

I will also add that if you want to use an event bus so that you can receive signals from anywhere within your code from anywhere else, without having to go through specific Node instances, there is a great tutorial by GDQuest that explains how to set up a basic yet function events bus system. Note that this tutorial was made for Godot 3, so the code will need to be adjusted to the new way of doing things :)

If my analysis of your issue was wrong, don't hesitate to correct me.

nathanhoad commented 11 months ago

Assuming a node is available in the current scene (eg. @onready var some_node: Node = %SomeNode) and it has a signal on it called did_a_thing then you can call it in the dialogue like this: do some_node.did_a_thing.emit(). It's then up to you to make sure the right other nodes are connected to that signal of that instance.