How do I call a function/emit a signal from another scene without using globals/singleton

Godot Version

4.3

Question

I want to be able to call a function from another scene without using globals/singletons.

I’m tried calling the function menu_function(“continue game”) and menu_function(“new game”) and signals continue_game.emit() and new_game.emit(). Both give the error regarding not being able to call the function on packed scene or invalid access to property on packed scene.

I’m not to sure about signals but the error seems to always be same. I have preloaded the slots_menu for this script

This is the other script (slot menu)

For the time being I’m just trying to print the string that I’ve called from my main menu call arguement( menu_function(“continue game”) and menu_function(“new game”) )

I don’t want to use Globals/singletons because it seems unecessary for the time being. Is there any other way?

Well, the error already tells you what’s up. You have to instantiate your scene, just using preload is not enough.

1 Like

You’re misundertanding how signals work, the signal needs to be called directly from the node you want that emit it, example, you should get the node reference in the scene tree with get_node() and in this reference you can call the emit. What you actually want is groups.

# In the slots menu script:
func _ready() -> void:
	add_to_group("slots_menu")

And whatever you want to call functions from slots menu:

get_tree().call_group("slots_menu", "function_name", parameters)

In your case would be:

get_tree().call_group("slots_menu", "menu_function", "continue game")

1 Like

How would I go about instantiating a scene? I’m not really well versed with that. Or anything for that matter :sweat_smile:

Docs: Nodes and scene instances — Godot Engine (stable) documentation in English

Basically you’d call slots_menu.instantiate() and add_child.

1 Like

It is very, very complicated :slight_smile:

const SLOTS_MENU: PackedScene = preload("res://scenes/slots_menu.tscn")

In a function somewhere:

var slots_menu_instance = SLOTS_MENU.instantiate()
add_child(slots_menu_instance)

This instantiates the preloaded packed scene. Then adds it to the scene tree. This is quite fundamental so I would read the docs as indicated by @ratrogue and if you have not done so, the tutorials are fun and excellent to learn with. Do them twice, once to get through it and see what is involved, a second time to make sure you understood it. The first run will probably take 3 to 4 hours, the second about an hour, the third (if you have the patience) about 30 mins.

1 Like

I think I still didn’t understand this. So I did the

add_to_group("slots_menu")

thing in slots menu script. Do I need to call the

get_tree().call_group("slots_menu", "menu_function", "continue game")

in the other scene(main menu)? I tried this but it doesn’t really do anything?

Yep that seems to work. Hehe I would read the doc but…
Yeah no I should really read the docs
Is instantiating like heavy on the system/unoptimized?

Yep that seems to work fine thanks allot!
Also would instantiating be unoptimized ? Or does it not matter much?

It certainly does not matter much TBH, but I had read that Godot was a bit slow at instantiating scenes somewhere (can’t recall where). But unless you are loading hundreds of scenes into the tree it really isn’t an issue. In my current game I am trying to do just that, and with about 300 actors (unoptimized as yet) my frame rate finally dipped a smidge under 60 FPS. I am currently in the process of refactoring them to be more efficient, they were quite bloated with code TBH.

1 Like

Oooh. Yeah makes sense. Thanks!

1 Like