Imagine a simple settings window with an option to choose custom fonts. A function takes the value and passes it down the line setting the ProjectSettings
gui/theme/custom_font
value to the correct font's file path. The get_setting
returns the correct value when asked. BUT there is no update after the change is made, i.e. I still see the default fonts being used (at runtime. To test it I just change fonts after key presses).
ProjectSettings.set_setting("gui/theme/custom_font", font_path)
As I understand what should happen after setting a new custom font is the project needs to be restarted (as indicated by the warning in the editor itself when you try to set it manually). So, how can I do it? I tried get_tree().reload_current_scene()
but it only reloads the scene and not the whole project (I'd say it rather "resets" it to its initial values/parameters).
Restarting the game
To completely restart the game, this is what you are supposed to do:
Call OS.set_restart_on_exit
passing true, so the game restart the next time it exits.
Be aware of this:
Note: This method is only effective on desktop platforms, and only when the project isn't started from the editor. It will have no effect on mobile and Web platforms, or when the project is started from the editor.
Call get_tree().quit()
to exit the game.
However, this is a XY problem. You don't want to restart the game, you want to change the font.
Changing fonts in runtime
To change the font in runtime, do not work with the default font in project settings.
Instead create a Theme
. The Theme
is a Resource
(you can create it as a Theme
resource file from the filesystem). And in it you configure the fonts and the rest of the UI appearance you want.
Then on the root Control
s of every scene, you configure the theme
to your Theme
... You do not need to set it on every Control
because they will take the Theme
from their parent, so you only need to set it on the top level Control
s.
Now, you should be able to change fonts of the Theme
in runtime, and the change would be reflected on every Control
that has it configured automatically. No restart needed.
Note: If you have set the theme
to your Theme
resource file via the Inspector, or if you preload
it form code, you should be getting the same instance. But if you use load
you might or might not get the same instance (due to the object lifespan and caching), and if you don't get the same instance, its changes would not be reflected elsewhere (you would have essentially loaded a copy).
The Theme
has a default_font
property that you can set. You can find it on the Inspector when you open your Theme
resource file in the editor. And make sure to set the default_font_size
too.
And you can directly set these properties from code in runtime. Again, I remind you that you preload
the Theme
resource file to work with it from code.
If you rather have more control, you can specify fonts (and font sizes) for different types...
You can do this in the Theme panel when you open the Theme
resource file in the editor.* So, for example, to change the font of Button
s, you specify the value "font" of the type "Button", which is different from the font for Label
s which is "font" of the type "Label". *Inheritance apply, so by setting the font for "Button" but not the font for "CheckBox" the CheckBox
gets the same font as Button
s.
You need to keep that in mind to change the font from code. As you might guess, you need to set_font
on the Theme
(which I remind you that you get by preload
ing the Theme
resource file). The set_font
method wants three parameters:
name
: the name of the value you are setting, e.g. "font".theme_type
: the type for which you are setting it, e.g. "Button".font
: The new font you want to set.Looking at my current Theme
, the fonts I set are for "Button", "Label", "LineEdit", "PopupMenu", "ProgressBar", "TabContainer", "TextEdit", "Tree" and "Window".