A signal doesn't get emitted and I can't figure out why
Asked Answered
G

3

0

In my scene with the root node named Parent there is a child scene called ItemParent. From the ItemParent scene I want to emit a signal under certain conditions to the Parent node. The function that determines said conditions works normally and I can confirm that because "here" is printed when the desired collision happens, however there is no print from the Parent node's side and I can't figure out what's wrong.

Bellow is the script that's attached to the ItemParent scene's root node

Here's the main scene. I want to emit the "spawn_item" signal from ItemParent to Parent

Here's the original node signal view tab

And as you can see it was properly connected

Though after getting help from Reddit I disconnected that signal and connected the nodes via code (inside of Parent)

And lastly here's the relevant func in the Parent node's attached script

The conditions in ItemParent's if statement are met. I know that since when the conditions occur I print "here" on line 24 and it is actually printed when the conditions are met. However "emitted" (from Parent node) isn't printed. So for some reason the signal just doesn't get emitted.
Also I should mention that the signal isn't emitted from ItemParent directly. Instead ItemParent is a parent scene with multiple scenes inheriting from it. The code above (first image) is a script attached to ItemParent, with each child (like item1, item2 etc) only having one script with the line "extends ItemParent". These child scenes are also added to the main scene dynamically by preloading them in Parent's script, instantiating them and then using add_child()


func _on_item_spawner_item_droppped(selection, pos): is the function that creates said children and it works properly
Things I've tried:
• spawn_item.emit(item_id, pos) was originally in line 21. Thinking that the item got deleted before it got the chance to emit the signal. That didn't work, even deleting the body.hide() and body.queue_free() didn't work.
• Exiting godot and reopening also didn't work, neither did disconnecting and reconnecting the signal, or restarting my PC
• Connecting the nodes via code instead of via the editor. Also didn't work

Greenfinch answered 27/11, 2023 at 7:31 Comment(0)
B
0

hmmm you could create a temporary item spawner dummy object with a fixed lifespan upon creep death event, then spawn stuff via temp spawner.

edit: For your problem, my wild guess would be variables like €item ot itemparent didn't get initialized when you try to connect them, you should try printing the value of item and item parent out in connect functions.

Barny answered 27/11, 2023 at 11:10 Comment(0)
D
0

Greenfinch These child scenes are also added to the main scene dynamically

Where do you connect the signal for each of those dynamically created scenes?

Darrendarrey answered 27/11, 2023 at 13:52 Comment(0)
G
0

Update, I eventually figured out what was wrong after some testing. Basically I never connected the dynamically created children to the parent node, I only connected ItemParent. To fix this, when I create an item (at _on_item_spawner_item_dropped(selection, pos)) after creating the child, I connect it to the Parent node like this item_array[selection].spawn_item.connect(_on_item_parent_spawn_item).
Also please don't use my code if you want to do something similar, instantiating scenes every frame isn't a good idea and the game crashes after about a minute or two due to lack of memory. Instead make a variable and instantiate the scene when the function to spawn a child is called. in my case that function is _on_item_spawner_item_dropped()

Greenfinch answered 27/11, 2023 at 21:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.