Can (node) paths in godot accept variables?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By jevans

Hi, I’m currently in the process of reorganizing my project and making some scripts (like the save function) into autoloads. What was the whole game before is now just one of several levels, so having a single, global save/load script seems wise, but unfortunatley it’s got a bunch of hard-coded paths to other nodes from its old configuration. I’d like to make these use placeholders where possible, so one funcion can grab from whichever scene is currently loaded.

I know paths can use strings, for example:

$"res://Level1/Level1.tscn"/player.position.x

seems to work

but

$Global.scene/player.position.x

obviously won’t. Is there any way to do something similar?

My most likely backup plan is to make more of the variables themselves global, but if there’s a way to leave them be, that’d be nice. Failing that, there are a bunch of ugly fixes I can make, like creating multiple copies of the function and picking between them with an if statement and the Global.scene variable, but I’d really like to find something more elegant. If you know of anything, please let me know.

:bust_in_silhouette: Reply From: Eric Ellingson

Could you use an AutoLoaded class to store that info and retrieve it from there instead?

So you could have:

# AutoLoadedClass.gd
extends Node

# initialize as empty Vector2
var player_position = Vector2()

Then in other scripts, whenever you change the player position, you can set also the value:

func _some_function(new_position):
    $Player.position = new_position
    AutoloadedClass.player_position = new_position

And retrieve the value the same way:

func _another_function():
    $Player.position = AutoloadedClass.player_position

Godot autoloading documentation

Thank you for your answer! I pretty much did this and it seems to be working. I kept the local save function, just gutted it down to four lines that grabbed values from the variables I was having trouble getting, and then called the global save function and passed it to them. That part’s working great.

Loading is kind of the same thing in reverse. The global load function does all the global variables for player, world state, dialogue tree, etc, then it needs to call the local load function, pass it those same variables, and let it put them where they belong and reset all the NPCs etc (one of those variables is a dict of all the relevant information for all of them).

The only problem I’m still having is calling the local load function from the global one (same reason as before) but it’s a smaller issue now, and worst case, I’ll try using a signal to get the data to it. Since I change scenes first, the only thing listening for the signal should be the correct local load function.

I think part of the reason I’m having such trouble with paths is that the autoload/global save_load script isn’t directly in the hierarchy, and I’m using the level changing code from Singletons (AutoLoad) — Godot Engine (3.0) documentation in English which seems to work with the actual files, and I’m not sure how to get their paths to work in gdscript.

Thank you again for your help, I really appreciate it!

jevans | 2019-02-04 18:23

Just for future reference for anyone has this problem, I didn’t end up using signals, I just had the global load function return the variables (in a dictionary, though an array would also work), then had the GUI pause menu script that called it convert them into individual variables and call the level-local load function to put them where they belonged.

This is probably not the right way to do this, but that’s kind of this game’s motto at this point, so at least it’s on brand.

func _on_LoadButton_pressed():
var dict= Global_Save_Load.load_game() #this one's the autorun
var flexible_save=dict["flexible_save"] #this has all my NPCs' locations on paths, etc
var pos_x=dict["pos_x"]
var pos_y=dict["pos_y"]
$"../.."/Save_Load.load_game(flexible_save, pos_x, pos_y) #this one's local to the level/instance

The way the level changing code works is to load new instances from the files, so the levels aren’t ever really in the same editor tab as the autoruns. I had trouble figuring out paths, and setting up the signals was difficult because the autoruns couldn’t see everything else, even though the local files can call on them. Bouncing all those values back through the pause menu seemed like the most efficient way to get the values from the global save function to the level-local one.

I only used a dictionary because I was troubleshooting an issue with the player’s position and didn’t want to worry I was doing something wrong with the order of values in the array.

jevans | 2019-02-04 21:27