关于 godot-ui-control
面向 Godot 4.7 的 UI 技能,介绍如何用 Control 节点构建响应式界面、设置主题并配置键盘和手柄焦点导航。适用于制作 HUD、菜单、背包、对话框和设置界面。
主要功能
- 01使用 Control 节点构建 UI
- 02通过锚点适配窗口尺寸
- 03使用容器排列子节点
- 04通过 Theme 统一样式
- 05配置键盘与手柄焦点导航
- 06连接按钮和控件信号
适用场景
- 01制作可适应窗口尺寸的菜单
- 02搭建 HUD、背包或设置界面
- 03让界面支持键盘和手柄导航
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ gamedev-skills/ awesome-gamedev-agent-skills --skill godot-ui-control安装后在 Claude Code 中输入/godot-ui-control确认已加载。
附带文件references/layout-and-theming.md
详细介绍
Godot UI / Control 节点(4.x)
使用 Control 锚点和 Container 节点布局响应式 UI,使用 Theme 设置样式,并让界面支持键盘和游戏手柄导航。适用于 Godot 4.7。
适用场景
- 使用派生自
Control的节点构建 HUD、菜单、物品栏、对话框或设置屏幕;安排能够适应窗口大小的 UI;设置主题;或配置手柄/键盘焦点导航。
不适用场景: 场景内的 2D 节点(Node2D/精灵)→ godot-nodes-scenes;
为 UI 转场添加动画 → godot-animation(Tween);卡牌手牌等类型专属 UI →
card-game/visual-novel。如需完整的输入重新绑定 → input-systems。
核心工作流
- 使用
Control节点构建 UI,而不是Node2D。Control 节点有矩形区域(位置 + 大小)、锚点,并参与焦点和主题设置。 - 使用锚点实现响应式布局。 锚点是父级矩形区域的比例(0–1),用于固定 Control 的边缘。使用编辑器的 布局 预设(左上、完整矩形、居中等),而不是手动放置像素。
- 让 Container 定位子节点。 将子节点放入
VBoxContainer、HBoxContainer、GridContainer、MarginContainer等容器中——容器会设置子节点的位置/大小;通过size_flags控制排列方式。不要在容器内设置子节点的锚点(容器会覆盖这些设置)。 - 使用
Theme设置样式。 将Theme资源赋给顶层 Control;子节点会继承该主题。仅在必要时通过主题覆盖逐节点调整。 - 配置焦点导航,让手柄/键盘能够在按钮之间移动;设置默认焦点控件,并定义相邻控件,或依赖自动相邻设置。
- 连接信号(
pressed、toggled、text_submitted、value_changed)。
模式
1. 使用锚点实现响应式布局(代码形式)
extends Control
func _ready() -> void:
# Stretch this panel to fill its parent (equivalent to the "Full Rect" preset).
anchors_preset = Control.PRESET_FULL_RECT
# Or set anchors manually: all four edges at the parent's far corners.
# anchor_left = 0; anchor_top = 0; anchor_right = 1; anchor_bottom = 1
2. 使用容器和按钮信号构建菜单
extends VBoxContainer # children stack vertically, auto-sized
func _ready() -> void:
for child in get_children():
if child is Button:
child.pressed.connect(_on_button_pressed.bind(child.name))
# Give the first button focus so a gamepad can navigate immediately.
if get_child_count() > 0:
(get_child(0) as Control).grab_focus()
func _on_button_pressed(which: StringName) -> void:
match which:
"PlayButton": get_tree().change_scene_to_file("res://game.tscn")
"QuitButton": get_tree().quit()
3. 大小标志:让一个子节点扩展以填充剩余空间
# In a HBoxContainer: a label on the left, a spacer that eats remaining width.
func _ready() -> void:
$Label.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
$Spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL # grows to fill
4. 为单个节点覆盖主题(无需完整的 Theme 资源)
func _ready() -> void:
# Per-node overrides: use add_theme_* (type-specific setters).
$Title.add_theme_font_size_override("font_size", 32)
$Title.add_theme_color_override("font_color", Color.GOLD)
$Panel.add_theme_stylebox_override("panel", preload("res://ui/panel.stylebox.tres"))
常见问题
- 混用手动定位和 Container。
Container的子节点无法自行设置位置/锚点——布局由容器负责。若要自由放置节点,请将其移出容器,或使用普通的Control/PanelContainer作为包装节点。 - 锚点与偏移量。 锚点是父级的比例;偏移量是相对于锚定点的像素差值。通过预设设置锚点,再使用偏移量微调。锚点设为 0 时,如果只设置位置,UI 就不会随窗口缩放。
- 使用
Node2D构建 UI。 父节点为Node2D的按钮/标签无法正确应用主题或获取焦点。请将 UI 保持在CanvasLayer/Control子树下。 - 手柄焦点丢失。 如果没有任何控件获得焦点,方向输入就不会生效。对初始控件调用
grab_focus(),并确保focus_mode不是FOCUS_NONE。 - Theme 与主题覆盖。
Theme资源为整个子树设置样式;add_theme_*则覆盖单个节点的设置。过度使用逐节点覆盖会破坏集中式主题管理。 rect_*属性已重命名。 Godot 3 中的rect_size/rect_position/rect_min_size在 4.x 中分别改为size/position/custom_minimum_size。- 完整矩形 Control 上的
mouse_filter可能会拦截原本要传给下方节点的点击;对于纯装饰面板,请设置为MOUSE_FILTER_IGNORE。
参考资料
- 关于锚点/偏移量的计算、各类 Container、构建/扩展 Theme 和 StyleBox 资源、配置焦点相邻控件,以及用于 HUD 的
CanvasLayer,请阅读references/layout-and-theming.md。
相关技能
game-ui-ux— 跨引擎 UI/UX:响应式缩放、安全区域、焦点导航、屏幕流程。godot-animation— 基于 Tween 的 UI 转场与动效强化。godot-signals-groups— 将 UI 事件连接到游戏逻辑。input-systems— 可重新绑定的输入和多设备焦点。card-game/visual-novel— UI 密集型游戏类型模板。
评论
支持 Markdown