英文:
How to make custom fonts visible at runtime? or How to redraw/update/restart the project in code?
问题
想象一个简单的设置窗口,其中有一个选项可以选择自定义字体。一个函数接受该值,并将其传递到设置ProjectSettings
的gui/theme/custom_font
,将其值设置为正确的字体文件路径。当询问时,get_setting
返回正确的值。但是在更改后没有更新,即我仍然看到默认的字体被使用(在运行时。为了测试它,我只是在按键后更改字体)。
ProjectSettings.set_setting("gui/theme/custom_font", font_path)
据我理解,在设置新的自定义字体后,应该重新启动项目(正如在编辑器中手动设置时所示的警告所示)。那么,我该如何做呢?我尝试过get_tree().reload_current_scene()
,但它只重新加载了场景,而不是整个项目(我更愿意说它“重置”到其初始值/参数)。
英文:
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).
答案1
得分: 1
重新开始游戏
要完全重新开始游戏,你应该执行以下操作:
-
调用
OS.set_restart_on_exit
并传递 true,以便在游戏下次退出时重新启动游戏。请注意:
注意: 此方法仅在桌面平台上有效,仅当项目不是从编辑器启动时才有效。在移动和Web平台上,或者从编辑器启动项目时,它将不会起作用。
-
调用
get_tree().quit()
来退出游戏。
然而,这是一个 XY问题。你不想重新启动游戏,而是想要更改字体。
更改运行时字体
要在运行时更改字体,请不要使用项目设置中的默认字体。
而是创建一个 Theme
。Theme
是一个 Resource
(你可以从文件系统中创建它作为一个 Theme
资源文件)。然后在其中配置你想要的字体和其他UI外观。
然后,在每个场景的根 Control
上,配置 theme
为你的 Theme
… 你不需要在每个 Control
上设置它,因为它们会从它们的父级那里获取 Theme
,所以你只需要在顶级 Control
上设置它。
现在,你应该能够在运行时更改 Theme
的字体,而更改将自动反映在每个已配置的 Control
上。无需重新启动。
注意: 如果你已经通过检查器将 theme
设置为你的 Theme
资源文件,或者通过代码 preload
它,那么你应该获得相同的实例。但如果你使用 load
,你可能会或可能不会获得相同的实例(由于对象寿命和缓存),如果你没有获得相同的实例,它的更改将不会在其他地方反映出来(实际上你加载了一个副本)。
Theme
有一个 default_font
属性,你可以设置它。你可以在编辑器中打开你的 Theme
资源文件时在检查器中找到它。并确保设置 default_font_size
。
你也可以在运行时直接从代码中设置这些属性。再次提醒你,你需要通过代码 preload
Theme
资源文件以便在代码中使用它。
如果你更喜欢更多的控制,你可以为不同类型指定字体(和字体大小)...
你可以在编辑器中打开 Theme
资源文件时,在 Theme
面板中执行此操作。因此,例如,要更改 Button
的字体,你需要指定类型“Button”的值“font”,这与Label
的字体不同,Label
的字体是类型“Label”的值“font”。继承会应用,因此通过为“Button”设置字体而不为“CheckBox”设置字体,CheckBox
将获得与 Button
相同的字体。
你需要记住这一点,以便从代码中更改字体。正如你可能猜到的那样,你需要在 Theme
上调用 set_font
(我再次提醒你,你通过 preload
Theme
资源文件来获取)。set_font
方法需要三个参数:
name
:你正在设置的值的名称,例如“font”。theme_type
:你正在为其设置的类型,例如“Button”。font
:你想要设置的新字体。
查看我的当前 Theme
,我设置的字体分别是“Button”、“Label”、“LineEdit”、“PopupMenu”、“ProgressBar”、“TabContainer”、“TextEdit”、“Tree” 和 “Window”。
英文:
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".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论