+4 votes

I was trying to change the font of a label on runtime, but for some reason the font wouldn't be able to load properly.

The code before was:

var f = Font.new()
f.create_from_fnt(*the path of the font*)
label.add_font_override("", f)

But before even reaching the method "addfontoverride", the engine would go all awry with "unicode error: invalid skip" and "unicode error: invalid utf8" on the output. The scene wouldn't crash, but the Label node I was working with wouldn't change its Font.

What am I doing wrong? Is there some other way to create a font? Using "ResourceLoader.load(path of the font)" doesnt work too - but instead of just displaying the Label text without anything changed, the text simply disappears.

in Engine by (304 points)

1 Answer

+2 votes
Best answer

Never mind, I got the error. After a very lucky shot (I was changing the methods almost randomly and forgot to track the arguments), I used "font" as the first argument for "addfontoverride", and now it works properly with a simple "load".

Is this the intended behaviour of the method? What is the meaning of this first argument?

Editing only to show the correct code:

label.add_font_override("font",load(*Path of the font*))
by (304 points)
edited by
The first argument is the "name" of the font used for storing it in a HashMap like this:

I guess that's why it can't/shouldn't be null.
But even when I used a random string, like "aaa", as the first argument, it wasn't working. It really only works if I use "font".

I think it's because I'm allocating the Labels dynamically too, so the default name of its font is "font", and it is the only way to access it. If it's because of that, than this is not clear on the documentation, and I'll try to push a change on it just to help it a little bit.

But I want to be sure of that first, haha.
It's because of the way controls and "themes" work. Simplest explanation, the string you put in that first argument isn't just whatever you want to call it, it's telling it WHICH font you want to override.

Fonts in controls are "theme items". What that means is all theme items default to whatever the "theme" sets that item to. Helpful for making broad changes to control objects across your whole project, but when you want to change an individual item of an individual control, you give that control an "override".

For example, Buttons have several "color" theme items, such as "font_color" and "font_color_pressed", for when it's just doing nothing and when it's being pressed, respectively. So if I wanted to change "font_color_pressed", I'd use
add_color_override("font_color", Color(1,0,0))
or something.

Now, this is a little silly with fonts, since I don't think there is any control that HAS more than one font property, and therefore you just end up telling it to override the font named "font". Again simplest explanation, it's this way because we want fonts to be part of themes.

Thank you Henrique so much.

I also found for RichTextLabels, you can do the same method above, but you can add in the font you want that corresponds to the bbcode name, like so:

To enable the [b]tags[/b]:
new.add_font_override("bold_font", load("res://OrbitronBold.fnt"))

And you wonder where I found the bold_font name, hover over the custom font properties in the inspector to get the name.

enter image description here

This is useful for interactive chat boxes (similar to Path of Exile) where you want to use mouse controls for item linkage, colors, bold names, images, etc.

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 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 webmaster@godotengine.org with your username.