CommunityCodierung & Entwicklunggithub.com

ziva-sh/godot-control-layout

Erstellt Godot 4 Control-Benutzeroberflächen, die sich in der Größe anpassen, anstatt abgeschnitten oder überlappend zu sein – Container vs. Anker, Anker-Voreinstellungen aus Code, Größenflags, custom_minimum_size, MarginContainer-Abstände, Label-Umbruch, mouse_filter, CanvasLayer-HUDs, Godot 4 Theme-Override-Namen (add_theme_color_override und Verwandte) sowie die Bildschirm-/Fenster-/Stretch-Einstellungen für mehrere Auflösungen.

Was ist godot-control-layout?

Dieses Skill bietet eine umfassende Anleitung zur Erstellung von sich anpassenden Godot 4 Control-Benutzeroberflächen, die typische Probleme wie Abschneiden oder Überlappung von UI-Elementen vermeidet. Der Fokus liegt auf der Verwendung von Containern zur Anordnung der Kindelemente, der korrekten Anwendung von Ankern nur für die Wurzelelemente und der Nutzung von minimalen Größen, um das Layout zu steuern. Es behandelt die wichtigsten Container-Typen (VBoxContainer, HBoxContainer, GridContainer, MarginContainer, etc.) und deren Größenflags, sowie die richtige Verwendung von `set_anchors_and_offsets_preset()` für ankernbasierte Positionierung. Das Skill deckt auch fortgeschrittene Themen ab: HUD-Erstellung mit CanvasLayer, Textumbruch und -beschneidung, Theme-Override-Namen in Godot 4 (im Vergleich zu Godot 3), Mausfilter zur Vermeidung von Eingabeverlusten und die Stretch-Einstellungen im Projekt für Multi-Resolution-Unterstützung. Es enthält eine Checkliste zur Fehlerbehebung für häufige UI-Probleme und praktische Code-Beispiele in GDScript.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ziva-sh/godot-skills/tree/HEAD/skills/godot-control-layout

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Steuerungslayout in Godot 4

Die meisten kaputten Godot-Benutzeroberflächen entstehen aus drei Fehlern: Kinder eines Containers von Hand positionieren, ein Steuerelement verankern ohne seine Versätze zurückzusetzen, und die Stretch-Einstellungen auf den Standardwerten lassen. Gestalten Sie mit Containern, verankern Sie nur die Wurzel jeder Benutzeroberfläche und lassen Sie minimale Größen den Rest bestimmen.

Container besitzen ihre Kinder

Ein Kind eines beliebigen Container (VBoxContainer, HBoxContainer, GridContainer, MarginContainer, PanelContainer, CenterContainer, ScrollContainer, FlowContainer) kann seine eigenen position, size oder Anker nicht behalten: der Container überschreibt sie beim nächsten Sortieren. Steuern Sie den Platzanteil eines Kindes mit:

  • size_flags_horizontal / size_flags_vertical: Control.SIZE_FILL (Standard), SIZE_EXPAND_FILL um restlichen Platz zu nehmen, SIZE_SHRINK_CENTER / SIZE_SHRINK_END um klein und ausgerichtet zu bleiben.
  • size_flags_stretch_ratio: Anteil am restlichen Platz zwischen expandierenden Geschwistern.
  • custom_minimum_size: die kleinste Größe, die das Kind akzeptiert. Container verkleinern ein Kind nie unter seine kombinierte Mindestgröße, wodurch Text und Schaltflächen nicht abgeschnitten werden.

Wählen Sie den Container nach Layout: Zeilen oder Spalten (VBoxContainer, HBoxContainer), ein Gitter (GridContainer mit columns), Abstände (MarginContainer, Abstände gesetzt durch Themen-Konstanten margin_left, margin_top, margin_right, margin_bottom), ein Hintergrund (PanelContainer, Style-Box panel), langer Inhalt (ScrollContainer mit einem Kind, das SIZE_EXPAND_FILL hat), umbrechende Elemente (HFlowContainer).

Anker nur für die Wurzel

Anker platzieren ein Steuerelement relativ zum Rechteck seines Elternteils und werden für den äußersten UI-Knoten verwendet. Verwenden Sie aus Code set_anchors_and_offsets_preset(). set_anchors_preset() verschiebt nur die Anker und behält die alten Versätze, sodass ein in Code erstelltes Steuerelement bei Größe (0, 0) bleibt.

Voreinstellungen: PRESET_FULL_RECT, PRESET_TOP_LEFT, PRESET_TOP_RIGHT, PRESET_BOTTOM_LEFT, PRESET_BOTTOM_RIGHT, PRESET_CENTER, PRESET_TOP_WIDE, PRESET_BOTTOM_WIDE, PRESET_LEFT_WIDE, PRESET_RIGHT_WIDE, PRESET_HCENTER_WIDE, PRESET_VCENTER_WIDE sowie die Mitte-Rand-Voreinstellungen wie PRESET_CENTER_TOP.

HUD auf einer CanvasLayer

Ein Control unter einem Node2D wird im Weltraum gezeichnet und bewegt sich mit der Camera2D. Platzieren Sie das HUD unter einer CanvasLayer, damit es auf dem Bildschirm bleibt; layer ordnet mehrere Canvas-Ebenen (höhere werden oben gezeichnet).

extends CanvasLayer

var score_label: Label


func _ready() -> void:
	var margin := MarginContainer.new()
	margin.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
	for side in ["margin_left", "margin_top", "margin_right", "margin_bottom"]:
		margin.add_theme_constant_override(side, 16)
	add_child(margin)

	var column := VBoxContainer.new()
	margin.add_child(column)

	var top_bar := HBoxContainer.new()
	column.add_child(top_bar)

	score_label = Label.new()
	score_label.text = "Score: 0"
	score_label.add_theme_font_size_override("font_size", 24)
	score_label.add_theme_color_override("font_color", Color.GOLD)
	top_bar.add_child(score_label)

	var spacer := Control.new()
	spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	spacer.mouse_filter = Control.MOUSE_FILTER_IGNORE
	top_bar.add_child(spacer)

	var pause_button := Button.new()
	pause_button.text = "Pause"
	pause_button.custom_minimum_size = Vector2(96, 40)
	top_bar.add_child(pause_button)


func set_score(value: int) -> void:
	score_label.text = "Score: %d" % value

Im Editor erstellt ist der gleiche Baum: CanvasLayer > MarginContainer (Layout: Full Rect) > VBoxContainer > HBoxContainer > Label, Control (Expand), Button.

Text, der nicht abgeschnitten wird

  • Ein Label mit gesetztem autowrap_mode benötigt eine Breite von irgendwoher. Innerhalb eines HBoxContainer mit Standard-Flags kollabiert es auf 1 Pixel Breite und wird sehr hoch. Geben Sie ihm SIZE_EXPAND_FILL oder ein custom_minimum_size.x.
  • Für einzeiligen Text in einem festen Raum setzen Sie text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS (oder clip_text = true).
  • Bevorzugen Sie add_theme_font_size_override("font_size", n) gegenüber dem Skalieren eines Steuerelements: scale ändert nicht die Größe, die Container reservieren.
extends VBoxContainer


func add_message(text: String) -> void:
	var label := Label.new()
	label.text = text
	label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
	label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	add_child(label)


func add_title(text: String) -> void:
	var label := Label.new()
	label.text = text
	label.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
	label.custom_minimum_size = Vector2(0, 32)
	add_child(label)

Klicks, die das Spiel nicht erreichen

mouse_filter entscheidet, ob ein Steuerelement Mauseingaben frisst. Die Vorgaben unterscheiden sich: einfaches Control, ColorRect und Panel verwenden MOUSE_FILTER_STOP, Container verwenden MOUSE_FILTER_PASS, Label verwendet MOUSE_FILTER_IGNORE. Ein Vollbild-Control oder ColorRect mit STOP schluckt jeden Klick, sodass _unhandled_input() im Spiel ihn nie sieht. Setzen Sie mouse_filter = Control.MOUSE_FILTER_IGNORE auf Überlagerungen, Abstandshaltern und dekorativen Rechtecken.

Theme-Overrides (Godot 4 Namen)

Godot 3Godot 4
add_color_override("font_color", c)add_theme_color_override("font_color", c)
add_font_override("font", f)add_theme_font_override("font", f)
(Schriftgröße lebte in DynamicFont)add_theme_font_size_override("font_size", 24)
add_stylebox_override("normal", sb)add_theme_stylebox_override("normal", sb)
add_constant_override("separation", 8)add_theme_constant_override("separation", 8)
add_icon_override("icon", tex)add_theme_icon_override("icon", tex)
custom_colors/font_color in .tscntheme_override_colors/font_color

Entfernen Sie eine Überschreibung mit dem passenden remove_theme_*_override(name). Für ein einheitliches Aussehen weisen Sie dem Wurzelsteuerelement eine einzelne Theme-Ressource zu, anstatt jeden Knoten zu überschreiben; Kinder erben sie.

Auflösung und Streckung

Stellen Sie diese in Projekteinstellungen > Anzeige > Fenster ein (gespeichert in project.godot):

  • display/window/size/viewport_width und viewport_height: die Basisauflösung, für die Sie entwerfen (Standard 1152 x 648).
  • display/window/stretch/mode: canvas_items für die meisten Spiele (UI und 2D skalieren flüssig), viewport für Pixel-Art, disabled für Werkzeuge. Godot 3s 2d-Modus ist canvas_items in Godot 4. Die Standardeinstellung ist disabled; Projekte, die in Godot 4.7 oder später erstellt wurden, beginnen mit canvas_items.
  • display/window/stretch/aspect: expand lässt verankerte UI bei breiteren oder höheren Bildschirmen zusätzlichen Platz nutzen; keep fügt schwarze Balken hinzu. Der Standard ist keep; Projekte, die in Godot 4.7 oder später erstellt wurden, beginnen mit expand.
  • display/window/stretch/scale_mode: integer für gestochen scharfe Pixel-Art.

Zur Laufzeit sind dieselben Einstellungen am Fenster: get_window().content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS und get_window().content_scale_aspect = Window.CONTENT_SCALE_ASPECT_EXPAND.

Checkliste, wenn die UI abgeschnitten oder falsch platziert ist

  1. Ist das Steuerelement ein Container-Kind mit handgesetzter position oder size? Verwenden Sie Größenflags und custom_minimum_size.
  2. Wurde die Wurzel nur mit set_anchors_preset() verankert? Verwenden Sie set_anchors_and_offsets_preset().
  3. Hat ein umbrechendes Label eine Breite?
  4. Ist das HUD unter einer CanvasLayer statt einem Node2D?
  5. Ist display/window/stretch/mode noch disabled, während sich die Fenstergröße ändert?
  6. Liegt ein unsichtbares Vollbild-Steuerelement mit MOUSE_FILTER_STOP obenauf?

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

ziva-sh/godot-4-api-pitfalls

Fixes Godot 3 APIs and GDScript syntax that AI assistants write into Godot 4 projects, such as KinematicBody2D, move_and_slide(velocity), export, onready, setget, yield, string connect(), instance(), rand_range, the Tween node, File, change_scene, Spatial, rect_* properties, Pool*Array, OS time functions and the old TileMap API. Use when writing, reviewing or porting GDScript for Godot 4.x, when a script fails with "not declared", "not found in base", "was removed in Godot 4" or "is not present

ziva-sh/godot-scene-organization

Structures Godot 4 projects so scenes stay reusable and references do not break - when to make a scene, a script or a Resource, instancing with @export PackedScene, preload and load, @onready and %UniqueName node access, _ready order, groups, autoloads, class_name, and resource UIDs with the .uid files added in Godot 4.4, including how to move or rename files safely. Use when creating new scenes or scripts, deciding how nodes find each other, adding global state or an event bus, moving or renami

ziva-sh/godot-signals

Godot 4 signal patterns and their failure modes - declaring typed signals, emit(), connect() and disconnect() with Callables, bind() and unbind(), lambdas, CONNECT_ONE_SHOT and CONNECT_DEFERRED, await on signals and timers, editor-made connections stored in .tscn files, and the call down, signal up rule. Use when wiring UI buttons, timers, Area2D or body events and custom game events, when replacing Godot 3 connect("signal", self, "method") or yield code, or when debugging "already connected", "

ziva-sh/godot-tilemaplayer

Correct Godot 4.3+ TileMapLayer code - set_cell(coords, source_id, atlas_coords), reading cells and custom data, erasing, coordinate conversion, terrains, tile collision through TileSet physics layers, finding the tile a body hit, and migrating from the deprecated TileMap node and its layer-index API. Use when placing, reading or erasing tiles from GDScript, building a TileSet in code, generating levels procedurally, handling tile collisions, or porting TileMap code from Godot 3 or Godot 4.0 to

Verwandte Skills