Is there auto font size like in Unity

Godot 4.2.1

Is there any built in features that make it so when text is too big for a label it shrinks to fit the label like the “Auto Font Size” feature in Unity. Or any code that would do something similar?

EDIT: mrcdk’s solution worked well for single line text, but I wanted it to work on multi line text, so I created this solution using what I had learned from mrcdk’s solution (namely the _set() function):

class_name AutoFontSizeLabel extends Label
## A label that will scale the font size to fit its size, betweem the min and max sizes.

## Smallest possible font size text can be in the label.
@export var minimum_size := 10

## Largest possible font size text can be in the label, also default font size when there is not much text.
@export var maximum_size := 20

func _ready():
	# Clip text must be true otherwise label just resizes rather than hiding lines,
	# which the update_font_size function relies on to resize font.
	clip_text = true

func _set(property, value):
	if property == "text":
		text = value
		add_theme_font_size_override("font_size", maximum_size)
		return true
	return false

func update_font_size():
	var font_size = get_theme_font_size("font_size")
	while get_visible_line_count() < get_line_count():
		font_size -= 1
		add_theme_font_size_override("font_size", font_size)

No, not out of the box.

I did an implementation to answer a similar question:

class_name AutoSizeLabel extends Label

@export var max_font_size = 56

func _ready() -> void:
	clip_text = true

func _set(property: StringName, value: Variant) -> bool:
	match property:
			# listen for text changes

	return false

func update_font_size() -> void:
	var font = get_theme_font("font")
	var font_size = get_theme_font_size("font_size")

	var line =
	line.direction = text_direction
	line.flags = justification_flags
	line.alignment = horizontal_alignment

	for i in 20:
		var created = line.add_string(text, font, font_size)
		if created:
			var text_size = line.get_line_width()

			if text_size > floor(size.x):
				font_size -= 1
			elif font_size < max_font_size:
				font_size += 1
			push_warning('Could not create a string')

	add_theme_font_size_override("font_size", font_size)

func _on_item_rect_changed() -> void:

Could you explain why you loop 20 times specifically ?

There was no reason at all, I just chose a number of iterations at random. You can tweak it and use whatever number you want.

1 Like