Issues with Label proportional resizing for proper responsive UI

Godot Version

v4.2.1.stable.official [b09f793f5]

Question

Hi!

I am currently implementing a responsive label sizing system via GDscript, because it is not a default feature in Godot.

For now I have a function which gets all the labels and buttons in the scene when the screen is resized. But for my system to work properly, I need to get the inital font size of every label directly, because otherwise all my nodes will get resized to the same size.

So I thought about doing it when the screen gets resized, or maybe by storing the nodes it in a dictionary when loaded to use it when the screen is resized, but I have tried multiple scripts and I cannot manage to find the correct way to program it.

Here’s my UI manager script :

extends CanvasLayer

# USE - UI animations, transitions, input signals and calls

@onready var menuScene = get_node('/root/MenuScene')
var viewportX
var viewportRatio

func _ready():
	
	# Window resizing signal
	get_viewport().size_changed.connect(_on_child_resized)
	
	var all_text= find_text(get_tree().get_root())

func _on_child_resized():
	# Call the find_labels function starting from the root of the scene tree
	var all_text= find_text(get_tree().get_root())
	#print("Number of Label nodes found:", all_text.size())
	
	# Get viewport width and font size ration
	# TEMPORARY - Proper algorithm for viewport ratio, with font inital size
	viewportX = get_viewport().size.x
	viewportRatio = viewportX * 0.01388
	
	# Function run to each stored text node
	for text in all_text:
		
		var initialFontSize = text.get_theme_font_size("font_size")
		print("Node : ", text, ", initial font size : ", initialFontSize)
		
		# Here is the funky part
		text.add_theme_font_size_override("font_size", text.get_theme_font_size("font_size") * viewportRatio/initialFontSize)
		print("Node n ° ", text.get_index(), " : ", text, ", Size : ", text.get_theme_font_size("font_size"))


# Recursive search for Label nodes in the scene tree
func find_text(node):
	var text = []

	# Check if the current node is a text
	# DEV - Resize system : may need more node types
	if node is Label or node is Button:
		# Add the Label node to the list of labels
		text.append(node)

	# Recursive search for Label nodes in the children of the current node
	for child in node.get_children():
		text += find_text(child)

	return text

If you have any suggestions please let me know, any help would be much appreciated.

Thanks !

UI scaling with the canvas_items stretch mode (or disabled + custom scale factor) is a built-in feature in Godot. See the Multiple resolutions documentation for details, specifically its Common use case scenarios section.

What’s not provided out of the box in Godot is automatically sizing a single Label depending on how much text it contains (so it fits in a given width), but doing this can be an accessibility issue if you let the text become too small.

You’re right, it’s not very obvious in the docs but there is a system built-in for that, I completely went over it. Thanks for the help!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.