The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

0 votes
var best_file
var newBest

func _process(delta):
    if get_tree().current_scene.name == "TRACK_1":
        best_file = "user://best_1.txt" 
    if get_tree().current_scene.name == "TRACK_2":
        best_file = "user://best_2.txt" 
    #and so on for all 10 tracks...

func _save_best():
    var file = File.new()
    file.open(best_file, File.WRITE)
    file.store_var(newBest)
    file.close()

func _load_best():
    var file = File.new()
    if file.file_exists(best_file):
        file.open(best_file, File.READ)
        newBest = file.get_var()
        file.close()
else:
    newBest = newBest

Basically, I want to use a single script for all the scenes and let it find out what scene it is and pick path accordingly. I thought the above written architecture would do the job, but it returns the following error: Invalid type in function "file_exists" in base "_File". Cannot convert argument 1 from Nil to String.

Though when I make separate scripts with corresponding var best_file = "user://best_n.txt", one for each, it works perfectly.

Is there any way to make one script work in all scenes? It should check what scene it is and give the corresponding path.

Thank you for your time!

Godot version 3.2.3
in Engine by (373 points)

1 Answer

0 votes
Best answer

It looks like You want to use export variables here.

What happens in your script is that best_file is nulkl at the start and it becomes string in process(). You didn't show it, but You call load function before process() can run, so an error occures, that File with path null can't be accessed.

when You introduce new variable You can do it like this :

export var newBest : String

Thanks to this, You can manually type desired path for each copy of this scene in editor, without making separate scripts for those scenes. One script, different variables. This way newBest will not be null on init() and You can refer to this variable anytime without null error.

Is this it, or did I take it too simply ?

by (8,188 points)
selected by

Thank you for the reply! That's how I ended up doing it:

var newBest = 0.0
var path = ["user://best_1.txt", "user://best_2.txt", "user://best_3.txt"]
var best_file = ""

func _ready():
    if get_tree().current_scene.name == "TRACK_1":
        best_file = str(path[0])
    if get_tree().current_scene.name == "TRACK_2":
        best_file = str(path[1])
    if get_tree().current_scene.name == "TRACK_3":
        best_file = str(path[2])
    _load_best()

As you mentioned I set the variable to be string by adding = "" and also I added an array of strings (paths) to choose from and converted them to str. Works like a charm!

I see
If You don't want to do so many repetitions in code You can do something like this :

func ready():
       best_file = "user://best_" + get_tree().current_scene.name.right(0) + ".txt"

This line will find number in your current scene name and build a path using this number.

Hey, that's a very smart and short way of doing it! I'll try that. Thanks!

I used your short method and it worked well, just wanted to thank you again! The only part I changed was ...name.right(6), instead of zero (it happened to crop from left to right). But the idea itself and its simplicity is 5 star!! That eliminated var path and the rows of unnecessary ifs. Hats off!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.