How do i exchange variables between scenes?

Godot Version

Godot v4.4

Question

I’m new to game dev and I’ve been looking for a way to do this for a while now, but haven’t been able to find one. There is a method I found called singleton or something, and another one being a global script, but those two don’t work for what I’m making.

The only thing I’ve thought of so far is using the _on_body_enetered(body) function to grab the variable whenever the two objects hit each other (e.g. body.variablename or body.functionname), but my project is gonna take too long for me to test it, and I don’t wanna risk working on it only to find out that it doesn’t work in the end.

If that method doesn’t work, is there any other way I can do this? I’m trying to make a very specific mechanic here, so any method I can try could help.

Hi,

Why does putting a variable in a global / singleton script not work for you. Would be nice to get some more detail.

With a global script you can create the variable and refer to it any where as long as you prefix it with the global script name:

Globals.myvariable

Ryn

The terms ‘scene’ and ‘node’ can be used interchangeably at times. Where ‘scene’ is referring specifically to the top level node (not arbitrary sub-scenes instanced within it) and it needs to be swapped out with another scene (i.e. switching from the main menu into a game, or changing levels, or however your game functions structurally), this is when the singleton / autoload pattern is useful.

If you want nodes to communicate with one another within a scene, using a singleton / autoload is a boondoggle. Your scene can store all these variables and provide all these functions by itself. It can manipulate its children, call their functions, access their variables, etc. This is completely sufficient when the children are created statically (i.e. you have a Player node you create in the editor).

Any node can call arbitrary functions on each other and access each other’s variables as well. Once you have a reference to a node, you can do pretty much whatever you like with it. The root of the problem is discoverability. How do nodes come to be aware of one another? There are a few approaches.

It is possible to walk the scene tree from any arbitrary point and search for a node which matches some criteria. Take a node, call get_children(), iterate that list, call get_children() and so on (implemented as a recursive function). Along the way, you can do type comparisons, check for whatever criteria you’re interested in, or stash them in an array for later use.

# Scene root
extends Node2D

var enemies :Array[Enemy] = []

func _ready() -> void:
	# ...
	recursive_search(self)
	# ...

func recursive_search(root :Node) -> void:
	for c in root.get_children():
		recursive_search(c) # search children
		if c is Enemy:
			# Here, we can stick c into an array of Enemies for later use,
			# or call some Enemy-specific functions
			enemies.append(e)

func _process(_delta :float) -> void:

	for e in enemies:
		e.go_forth_and_commit_evil()

Another strategy would be to use signals. These could either be built-in signals, like those triggered by input or physics events, or they can be bespoke signals created to represent more abstract events which only have meaning in the context of your game. Signals can be emitted with parameters, (i.e. a reference to the node which caused the signal to be emitted), and then any nodes responding to the signal can directly access that node’s functions and properties.

Signals are part of the general design pattern in Godot to “Call down, signal up.” A parent node should be aware of its children, and can just call their functions and access their properties. This handles communication down the tree. Children, meanwhile, generally shouldn’t rely on any state within their parents. Instead, they emit signals which are optionally subscribed to by the parent. This allows communication up the tree.

In situations like this, I highly recommend building a minimal proof-of-concept in another project (or an isolated scene), for exactly the reason you state. It might turn out to be a dead end and a waste of time, but in that case you learned, you didn’t break anything, and you didn’t waste an enormous amount of time trying to implement it at scale. My current project has more test scenes than actual gameplay.

Games are complex. They have a lot of moving parts. It is inevitable that things aren’t going to work out perfectly the first time around. It is inevitable that we will have to revise and refactor certain systems. We can try to anticipate it and limit it, but it is basically part of the process.

Idk why but I never thought of making test scenes for this. I’m not sure if you’re ideas here will work for this, but somethings telling me I can figure something out with the signals. Though I don’t really understand them much, specifically the custom ones, this’ll be useful for actually figuring them out in the future.
Ty for the help riot doggo

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.