Communityコーディング&開発github.com

ziva-sh/godot-control-layout

Godot 4でコントロールUIを構築するためのスキル。コンテナ、アンカー、サイズフラグ、テーマオーバーライド、ストレッチ設定を利用して、UI要素のクリッピングや重なりを防ぎます。メニューやHUD、ダイアログ、インベントリ画面の作成・修正時に役立ちます。

godot-control-layout とは?

このスキルは、Godot 4におけるコントロールレイアウトのベストプラクティスを網羅しています。多くのUI不具合は、コンテナの子要素を手動で配置したり、アンカーを設定した後にオフセットをリセットしなかったり、ストレッチ設定をデフォルトのままにしておくことで発生します。このスキルでは、コンテナによるレイアウト(VBoxContainer、HBoxContainer、GridContainerなど)の適切な使い方、各UIのルートにのみアンカーを設定する方法、サイズフラグとcustom_minimum_sizeで子要素のサイズを制御する方法を説明します。また、CanvasLayerを使用したHUDの実装、テキストのクリッピングを防ぐLabelの設定(autowrap_mode、text_overrun_behavior)、マウスフィルターの適切な設定、Godot 4のテーマオーバーライド名(add_theme_color_overrideなど)、解像度とストレッチ設定(display/window/stretch)についてもカバーしています。さらに、UIが切れたり重なったりした場合のチェックリストも提供しており、Claude Code、Cursor、Codexなど、Godot 4でのUI開発に取り組むあらゆるAIエージェントや開発者にとって実用的なリソースです。

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

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Godot 4 におけるコントロールレイアウト

GodotのUIが壊れる原因のほとんどは、次の3つの間違いから来ています。コンテナの子要素を手動で配置する、アンカーを設定してもオフセットをリセットしない、ストレッチ設定をデフォルトのままにする。コンテナでレイアウトし、アンカーは各UIのルートにのみ設定し、最小サイズですべてを制御しましょう。

コンテナは子要素を所有する

Container(VBoxContainer、HBoxContainer、GridContainer、MarginContainer、PanelContainer、CenterContainer、ScrollContainer、FlowContainer)の子要素は、自身のposition、size、アンカーを保持できません。コンテナは次のソートでそれらを上書きします。子要素のスペースの配分は以下で制御します。

  • size_flags_horizontal / size_flags_vertical: Control.SIZE_FILL(デフォルト)、余ったスペースを取るSIZE_EXPAND_FILL、小さく整列したままにするSIZE_SHRINK_CENTER / SIZE_SHRINK_END。
  • size_flags_stretch_ratio: 展開する兄弟間での余ったスペースの分配率。
  • custom_minimum_size: 子要素が受け入れる最小サイズ。コンテナは子要素をその結合最小サイズより小さく縮めることはありません。これにより、テキストやボタンが切り取られるのを防ぎます。

コンテナはレイアウトに応じて選択します。行または列(VBoxContainer、HBoxContainer)、グリッド(columnsを指定したGridContainer)、パディング(MarginContainer、テーマ定数margin_left、margin_top、margin_right、margin_bottomで設定)、背景(PanelContainer、スタイルボックスpanel)、長いコンテンツ(SIZE_EXPAND_FILLを持つ1つの子要素を持つScrollContainer)、折り返しアイテム(HFlowContainer)。

アンカーはルートのみに

アンカーは、コントロールをその親の矩形に対して相対的に配置し、最も外側のUIノードに使用するものです。コードからは、set_anchors_and_offsets_preset()を使用します。set_anchors_preset()はアンカーのみを移動し、古いオフセットを保持するため、コードで作成されたコントロールはサイズ(0, 0)のままになります。

プリセット: 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、およびPRESET_CENTER_TOPなどの中央端プリセット。

CanvasLayer上のHUD

Node2Dの下にあるControlはワールド空間に描画され、Camera2Dとともに移動します。HUDをCanvasLayerの下に置くと、画面に固定されます。layerは複数のキャンバスレイヤーを順序付けます(高い値ほど手前に描画されます)。

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

エディタで構築する場合、同じツリーは次のようになります: CanvasLayer > MarginContainer (Layout: Full Rect) > VBoxContainer > HBoxContainer > Label, Control (Expand), Button。

クリッピングしないテキスト

  • autowrap_modeが設定されたLabelには、どこかから幅が必要です。デフォルトのフラグを持つHBoxContainer内では、幅が1ピクセルに縮み、非常に高くなります。SIZE_EXPAND_FILLまたはcustom_minimum_size.xを設定してください。
  • 固定スペース内の1行テキストの場合は、text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS(またはclip_text = true)を設定します。
  • コントロールのスケーリングよりもadd_theme_font_size_override("font_size", n)を推奨します。scaleはコンテナが予約するサイズを変更しません。
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)

ゲームに届かないクリック

mouse_filterは、コントロールがマウス入力を消費するかどうかを決定します。デフォルトは異なります。通常のControl、ColorRect、PanelはMOUSE_FILTER_STOP、コンテナはMOUSE_FILTER_PASS、LabelはMOUSE_FILTER_IGNOREを使用します。STOPが設定されたフルスクリーンのControlまたはColorRectは、すべてのクリックを飲み込み、ゲーム内の_unhandled_input()はそれを見ることができません。オーバーレイ、スペーサー、装飾的なRectにはmouse_filter = Control.MOUSE_FILTER_IGNOREを設定してください。

テーマオーバーライド(Godot 4名)

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)
(フォントサイズは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)
.tscn内のcustom_colors/font_colortheme_override_colors/font_color

対応するremove_theme_*_override(name)でオーバーライドを削除します。一貫した外観にするには、各ノードを個別にオーバーライドする代わりに、ルートコントロールに1つのThemeリソースを割り当てます。子要素はそれを継承します。

解像度とストレッチ

これらはプロジェクト設定 > 表示 > ウィンドウで設定します(project.godotに保存されます)。

  • display/window/size/viewport_width および viewport_height: 設計する基本解像度(デフォルト1152 x 648)。
  • display/window/stretch/mode: ほとんどのゲームではcanvas_items(UIと2Dがスムーズにスケール)、ピクセルアートではviewport、ツールではdisabled。Godot 3の2dモードはGodot 4ではcanvas_itemsです。デフォルトはdisabled。Godot 4.7以降で作成されたプロジェクトはcanvas_itemsで始まります。
  • display/window/stretch/aspect: expandはアンカー付きUIがより広いまたは高い画面で余分なスペースを使用できるようにします。keepは黒帯を追加します。デフォルトはkeep。Godot 4.7以降で作成されたプロジェクトはexpandで始まります。
  • display/window/stretch/scale_mode: ピクセルアートを鮮明にするにはinteger。

実行時には同じ設定がウィンドウにあります: get_window().content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS および get_window().content_scale_aspect = Window.CONTENT_SCALE_ASPECT_EXPAND。

UIが切れたり配置がおかしい場合のチェックリスト

  1. コンテナの子要素に手動でpositionやsizeが設定されていませんか?サイズフラグとcustom_minimum_sizeを使用してください。
  2. ルートがset_anchors_preset()だけでアンカー設定されていませんか?set_anchors_and_offsets_preset()を使用してください。
  3. 折り返しLabelに幅が設定されていますか?
  4. HUDはNode2DではなくCanvasLayerの下にありますか?
  5. ウィンドウサイズが変更されているのにdisplay/window/stretch/modeがまだdisabledになっていませんか?
  6. 不可視のフルスクリーンコントロールにMOUSE_FILTER_STOPが設定されていて、上に重なっていませんか?

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

関連スキル