Passing/connecting variables between scripts/scenes

4.3 Stable

Question
Hello! First post on the forum.
Currently, I am trying to figure out how to connect variables between scenes so that the value remains constant between scripts.
I have already heard of autoloads, but I am a little confused on how to use them for this purpose, and there appear to be multiple downsides to using them for a lot of variables, so I was wondering if there were other methods to connecting variables across scripts. I am also curious if dictionaries could be used to circumvent having to create a large amount of autoloads.
I also heard about the possibility of connecting them with functions, but I am unsure how to set this up so that the value of the variable could still be changed.

One option would be to create a class with static variables.
Example:

# foo.gd
class_name Foo

static var is_godot = true
# bar.gd
func _ready():
    print(Foo.is_godot) # true

I don’t quite know what you mean by ā€œconnecting them with functionsā€, but you can use setters and getters to run code whenever a property is set or accessed.
Example:

var two_plus_two = 4:
    set(value):
        if value != 4:
            OS.crash("Two plus two must equal 4!")
        two_plus_two = value

func _ready():
    two_plus_two = 5 # Would crash the game

The idea of connecting the variables with a function was something that I had heard of in a tutorial I watched. The basic idea, from what I understood, was that it was a function that simply returned the value of a variable when called, and could be called from another script because it was a function.

Also, I looked into autoloads a little more and they actually seem to be the best option for what I’m trying to do, as I previously misunderstood autoloads for some reason only being able to store one variable per autoload. I don’t know why I thought this, but it resulted in me preferring to avoid them as I thought I would need a lot of autoloads instead of just one.

If I understand what you mean, this wouldn’t be hard to implement:

var foo = true

func get_foo():
    return foo
var foo = true

func get_foo():
    return foo

func set_foo(value):
    foo = value

However, I don’t see the point of this when you can get and set variables from another script without functions.

Sorry, to clarify, I meant that I’m unsure of how to set the values for a variable that is contained inside of a dictionary, or if that’s even possible.

Never mind on the adding to dictionaries question, I somehow managed to miss an entire section of the documentation.

I am currently having difficulties actually using a variable from an autoload. I am getting the error: ā€œInvalid access to property or key ā€˜global_1’ on a base object of type ā€˜Node (global_variables.gd)’.ā€ My code is as follows:

# In the script attempting to access the variable:
var global_1 = (global.global_1)

# On the autoload's script:
var global_1: int = 1

If it helps, as extra info, the autoload itself is just a free-floating script and not attached to any node.

Code like that works as intended for me. The problem may be elsewhere.
Can you show more of your code?

Sure, but the only other code I have written that I think could interact is just a function that prints the value for global_1 when a button is pressed in the scene that’s attempting to use global_1.

# > used as a stand-in for indents
func on_print_example_pressed() -> void:
> print (global_1)

with a signal connecting said button to the function.
For a wider context to the scene itself, it’s a panel of buttons that I am using to test out methods of compiling multiple variables from across the project into a dictionary for saving to a JSON file, but none of the code for actually compiling the dictionary has been written yet as I realized I didn’t actually know how to grab the variables in the first place. Now, here’s the entirety of the scene’s script. (it’s moderately unorganized:)

extends Node2D


var example_value = 1
var file_number
var example_1
var path_dictionary
var var_path
var global_1 = (global.global_1)

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	pass

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	$RichTextLabel.set_text(str(example_value))

# This function will create the dictionary variable that will be saved to the JSON file.
func create_save_dict():
	for var_name in path_dictionary:
		var_path = path_dictionary[var_name]

# This function will be for the final process of saving to the file
func save_to_file(file_number):
	print(file_number)
	
	# 
	
	# learn about callables.
	return 
	pass



func _on_plus_one_to_value_pressed() -> void:
	# pass # Replace with function body.
	example_value += 1

func _on_minus_one_to_value_pressed() -> void:
	# pass # Replace with function body.
	example_value -= 1


func _on_print_example_pressed() -> void:
	print (global_1)
	


func _on_main_1_path_dictionary_signal(path_dictionary: Variant) -> void:
	pass # Replace with function body.

The function at the very bottom was me attempting an experiment with passing variables over signals, but that hasn’t gone anywhere.
Edit just after posting: I have no clue why that second block quote is entirely gray.

Also, the code in the autoload itself is as follows:

extends Node

var global_1: int = 1

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	pass

I don’t see anything wrong with your code, and it works perfectly fine for me. I hate to say it, but I simply don’t know what the problem could be. The one thing I would check would be the autoload configuration in the project settings.
For what it’s worth, I hope you’re able to find a solution.

Alright, thanks for the help! If I find a solution for my error, I’ll post it and mark it as the solution the thread.

OK, oddly enough, just deleting the script and making a new one fixed it. I have no clue why it wasn’t working previously, but a fix is a fix. Again, thanks for the help!
(Since this is marked as the solution, please read through thread for actual info on topic.)

2 Likes