Well I found the solution, If I set the custom_minimum_size and set size to it, godot will automatically set it to the min size for vertical alignment to work.
label.custom_minimum_size = Vector2(new_size.x, 0)
label.size = label.custom_minimum_size
Just need to make sure the label settings are applied first.
This is the updated code, ignore the added anchoring stuff, that was just to simplify some of the stuff I was doing.
func create_label(new_text: String, new_position: Vector2, new_size: Vector2, new_fontsize: float, new_alignment: int) -> Label:
var label := Label.new()
label.text = new_text
# Apply font settings
var label_settings := LabelSettings.new()
label_settings.font = ThemeDB.fallback_font
label_settings.font_size = new_fontsize
label.label_settings = label_settings
# Set correct size
label.custom_minimum_size = Vector2(new_size.x, 0)
label.size = label.custom_minimum_size
# Set Anchoring (Centering) IGNORE THIS FOR SOLUTION
label.set_anchors_preset(Control.PRESET_CENTER)
label.pivot_offset = label.size * 0.5 # Center pivot to match Godot Editor behavior
# Adjust position to respect anchoring INGNORE THIS FOR SOLUTION
label.position = new_position - label.size * 0.5
# Set alignment
label.horizontal_alignment = new_alignment
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
# Debugging: Add a ColorRect to visualize label bounds
var debug_rect := ColorRect.new()
debug_rect.size = label.size
debug_rect.color = Color(1, 0, 0, 0.3) # Semi-transparent red
label.add_child(debug_rect)
return label
Now I can just set
label.custom_minimum_size = new_size
and it should just resize it if its too small automatically.