Alternatives to get_tree().change_scene_to_file for a language change with a Button?

Godot Version

4.2.1

Question

I’m creating a Settings scene, I have only two languages (english and spanish), I control the language change with a Button, the language changes but the effect is not immediate in the settings scene. The language remains in the scene, if you return to main screen the language changes correctly, if you enter Settings scene the change then is applied.
I’ve solved it with get_tree function, but I can’t find an alternative way to do it.

Have you tried using the translation system? What kind of changes are you making?

Hi, I have a Button to change language for every text in the game. So, every Button or Label node needs this change from my Options scene.
Due they are only two languages, I’m using a button as a switch. So far, so good.
The only “problem” is that this language change occurs, without the get_tree instruction, only when you change to another scene (Main Menu screen in my design), so the texts in Options scene remain in the current active language until you change scene. With get_tree, calling the same scene, I’m forcing the change. Just want to know if there is another instruction capable.

Have you read this? And tried the methods there?

As @athousandships already mentioned, I would really advise you to use the built in translation system. It is exactly made for this.

That being said, if you want to roll your own system you will need:

  • persistent location to store the current language (for example an autoload)
  • each node with text needs a method to set the text according to the current language
  • each node with text should automatically call that method when entering the tree (so on ready)
  • whenever you change the language, you will need a way to trigger that method for all nodes with text that are already in the tree

In practice, your autoload could look like this:

extends Node

enum { EN, DE }

signal changed(new_lang)

var current := EN:
    set(value):
        current = value
        language_changed.emit(value)

Assuming you configure that script as an autoload called Language, you can use it like this on your labels and similar nodes:

extends Label

func _ready():
    update_text()
    Language.changed.connect(update_text)

func update_text():
    match Language.current:
        Language.EN: text = "English text"
        Language.DE: text = "German text"

With this setup, all you need to do to change the language is setting it like this:

Language.current = Language.DE

Due to the setter method, it will automatically emit the changed signal, so all nodes that connected to the signal will get the update.

1 Like