Godot Version
v4.7.2.stable.official [ed1daf0bf]
Question
My game has a few different fonts, and in order to quickly switch between them and change custom_minimum_size to adapt to them, I added a function that does exactly that.
@export var font_style: Styles:
set(value):
font_style = value
update_font_style() # load the fonts
match value:
Styles.DIALOG:
custom_minimum_size = MIN_SIZE_DIALOG
Styles.DIALOG_SMALL:
custom_minimum_size = MIN_SIZE_DIALOG
Styles.MENU:
custom_minimum_size = MIN_SIZE_MENU
Styles.TITLE_CARD:
custom_minimum_size = MIN_SIZE_TITLE_CARD
if font_style == Styles.DIALOG or font_style == Styles.DIALOG_SMALL:
text_color = ColorPresets.REGULAR
elif font_style == Styles.TITLE_CARD:
text_color = ColorPresets.GOLD
However, while this is really handy when I need to change the font style, it’s not so handy when my labels change their minimum size after a reload. So how can I say something like “I want you to change minimum size when you don’t have a custom font resource or if you have one but it’s not the same as the one you already have loaded”? I tried if not has_theme_font_override("font"): update_font_style(), but that doesn’t work since when the node is initialized, it doesn’t have a font loaded either way
Is this an editor script? Do you change font_style at run time? Maybe you can add if Engine.is_editor_hint() if you do only use this export for changing in-editor?
I know it’s common enough to use await ready to delay setters until the node is in the scene tree, maybe you could check if get_parent() returns null to determine if it isn’t in the scene.
I think it would still mess things up but only when the scene is reloaded in the editor, since it still has to load the font resource and all
But since I usually append my labels as children of other nodes, wouldn’t it never return null?
Then maybe await ready is what you want, maybe sharing update_font_style() would help clarify what data you are dependent on, and what exactly is going wrong vs what you expect
it should be non-null, to see it in the scene at all get_parent must be non-null. But nodes aren’t yet in the scene at the time of @export’s initialization, at least as I understand it get_parent() may return null at that time, could be wrong.
There’s a common idiom for setters that need to run some code only if some initialization condition is met. It’s typically done for ready state but can be used for any custom state.
In the setter, run the dependent code only if condition is met. When some other part of the code initializes the condition - call the setter explicitly immediately afterwards.
@export var foo:
set(value):
foo = value
if is_node_ready():
# do dependent stuff
func _ready():
foo = foo
Didn’t it work this way until some update? Or did I get it wrong? Because I explicitly have font_size set an extra time in _ready() and I think I wouldn’t’ve had it if it always worked the way it does now
Edit: okay wait this works in the editor but not in the game for some reason
We don’t know what your actual condition is. It may still not be met when this node’s _ready() is called.