godot-ui-control
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGodot UI / Control nodes (4.x)
Godot UI / Control nodes (4.x)
Lay out responsive UI with anchors and nodes, style it with a
, and make it navigable by keyboard and gamepad. Targets Godot 4.3+.
ControlContainerTheme使用锚点和节点布局响应式UI,通过设置样式,并使其支持键盘和游戏手柄导航。适用于**Godot 4.3+**版本。
ControlContainerThemeWhen to use
适用场景
- Use when building HUDs, menus, inventories, dialog boxes, or settings screens with
-derived nodes; arranging UI that adapts to window size; theming; or wiring focus navigation for controller/keyboard.
Control
When not to use: in-world 2D nodes (/sprites) → ;
animating UI transitions → (Tween); genre UIs like card hands →
/. For full input rebinding → .
Node2Dgodot-nodes-scenesgodot-animationcard-gamevisual-novelinput-systems- 适用于使用派生节点构建HUD、菜单、背包、对话框或设置界面;布局可适配窗口大小的UI;设置主题;或为控制器/键盘配置焦点导航时。
Control
不适用场景: 场景内2D节点(/精灵)→ 参考;UI过渡动画 → 参考(Tween);卡牌手牌等特定类型UI → 参考/;完整输入重绑定 → 参考。
Node2Dgodot-nodes-scenesgodot-animationcard-gamevisual-novelinput-systemsCore workflow
核心工作流程
- Use nodes for UI, not
Control. Controls have a rect (position + size), anchors, and participate in focus/theming.Node2D - Anchor for responsiveness. Anchors are fractions (0–1) of the parent rect that the Control's edges stick to. Use the editor's Layout presets (Top-Left, Full Rect, Center, etc.) instead of hand-placing pixels.
- Let Containers position children. Put children in a ,
VBoxContainer,HBoxContainer,GridContainer, etc. — the container sets their position/size; you control flow withMarginContainer. Don't set child anchors inside a container (it overrides them).size_flags - Style with a . Assign a
Themeresource on a top Control; children inherit it. Override per-node with theme overrides only when necessary.Theme - Wire focus so gamepad/keyboard can move between buttons; set a default focused control and define neighbors or rely on auto-neighbor.
- Connect signals (,
pressed,toggled,text_submitted).value_changed
- 使用节点构建UI,而非
Control。Control节点包含矩形(位置+尺寸)、锚点,并支持焦点和主题功能。Node2D - 利用锚点实现响应式布局。锚点是父节点矩形的比例值(0–1),Control节点的边缘会贴合锚点位置。使用编辑器的布局预设(左上、全屏、居中等),而非手动设置像素位置。
- 让Container节点自动定位子节点。将子节点放入、
VBoxContainer、HBoxContainer、GridContainer等容器中——容器会设置子节点的位置/尺寸;你可以通过MarginContainer控制布局流。不要在容器内设置子节点的锚点(这会被容器覆盖)。size_flags - 使用设置样式。在顶层Control节点上分配
Theme资源;子节点会继承该主题。仅在必要时通过主题覆写为单个节点设置样式。Theme - 配置焦点,使游戏手柄/键盘可在按钮间切换;设置默认聚焦的Control节点,定义相邻焦点或依赖自动相邻功能。
- 连接信号(、
pressed、toggled、text_submitted)。value_changed
Patterns
模式示例
1. Responsive layout with anchors (code form)
1. 锚点实现响应式布局(代码形式)
gdscript
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 = 1gdscript
extends Control
func _ready() -> void:
# 让此面板拉伸填充父节点(等同于“全屏”预设)。
anchors_preset = Control.PRESET_FULL_RECT
# 或者手动设置锚点:四个边缘均贴合父节点的角落。
# anchor_left = 0; anchor_top = 0; anchor_right = 1; anchor_bottom = 12. A menu built from containers + button signals
2. 基于容器+按钮信号构建的菜单
gdscript
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()gdscript
extends VBoxContainer # 子节点垂直堆叠,自动调整尺寸
func _ready() -> void:
for child in get_children():
if child is Button:
child.pressed.connect(_on_button_pressed.bind(child.name))
# 让第一个按钮获得焦点,以便游戏手柄可立即导航。
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. Size flags: make one child expand to fill leftover space
3. 尺寸标志:让单个子节点填充剩余空间
gdscript
undefinedgdscript
undefinedIn a HBoxContainer: a label on the left, a spacer that eats remaining width.
在HBoxContainer中:左侧是标签,右侧是占据剩余宽度的间隔器。
func _ready() -> void:
$Label.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
$Spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL # grows to fill
undefinedfunc _ready() -> void:
$Label.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
$Spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL # 自动扩展填充
undefined4. Theme override for one node (without a full Theme resource)
4. 单个节点的主题覆写(无需完整Theme资源)
gdscript
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"))gdscript
func _ready() -> void:
# 单个节点覆写:使用add_theme_*(特定类型的设置器)。
$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"))Pitfalls
常见陷阱
- Mixing manual position with Containers. A child of a cannot set its own position/anchors — the container owns layout. To free-place, take the node out of the container or use a plain
Container/Controlwrapper.PanelContainer - Anchors vs offsets. Anchors are fractions of the parent; offsets are pixel deltas from the anchored point. Set anchors via presets, then nudge with offsets. Setting only position while anchors are at 0 makes UI not scale with the window.
- for UI. Buttons/labels parented under a
Node2Dwon't theme or take focus correctly. Keep UI under aNode2D/CanvasLayersubtree.Control - Focus lost on gamepad. If nothing is focused, directional input does nothing. Call
on an initial control and ensure
grab_focus()is notfocus_mode.FOCUS_NONE - Theme vs theme override. A resource styles a whole subtree;
Themeoverrides one node. Overusing per-node overrides defeats centralized theming.add_theme_* - properties are renamed. Godot 3's
rect_*/rect_size/rect_positionare nowrect_min_size/size/positionin 4.x.custom_minimum_size - on a full-rect Control can swallow clicks meant for nodes beneath it; set
mouse_filteron purely decorative panels.MOUSE_FILTER_IGNORE
- 手动位置与Container混用。的子节点无法自行设置位置/锚点——容器拥有布局控制权。如需自由放置,将节点移出容器,或使用普通
Container/Control作为包装器。PanelContainer - 锚点与偏移混淆。锚点是父节点的比例值;偏移是锚点位置的像素增量。通过预设设置锚点,然后用偏移微调。仅设置位置而锚点为0时,UI将无法随窗口缩放。
- 使用构建UI。父节点为
Node2D的按钮/标签无法正确应用主题或获取焦点。应将UI置于Node2D/CanvasLayer子树之下。Control - 游戏手柄焦点丢失。若没有任何节点获得焦点,方向输入将无效。在初始Control节点上调用,并确保
grab_focus()未设置为focus_mode。FOCUS_NONE - 主题与主题覆写混淆。资源为整个子树设置样式;
Theme仅覆写单个节点。过度使用单个节点覆写会破坏集中式主题管理。add_theme_* - 属性重命名。Godot 3中的
rect_*/rect_size/rect_position在4.x版本中已更名为rect_min_size/size/position。custom_minimum_size - **全屏Control节点的**可能会遮挡下方节点的点击操作;对于纯装饰性面板,应设置为
mouse_filter。MOUSE_FILTER_IGNORE
References
参考资料
- For the anchor/offset math, every Container type, building/extending Theme and StyleBox
resources, focus neighbor wiring, and for HUDs, read
CanvasLayer.references/layout-and-theming.md
- 关于锚点/偏移的计算逻辑、每种Container类型的用法、Theme和StyleBox资源的创建/扩展、焦点相邻配置,以及用于HUD的,请阅读
CanvasLayer。references/layout-and-theming.md
Related skills
相关技能
- — cross-engine UI/UX: responsive scaling, safe areas, focus navigation, screen flow.
game-ui-ux - — Tween-based UI transitions and juicing.
godot-animation - — connecting UI events to game logic.
godot-signals-groups - — rebindable input and multi-device focus.
input-systems - /
card-game— UI-heavy genre templates.visual-novel
- —— 跨引擎UI/UX:响应式缩放、安全区域、焦点导航、屏幕流程。
game-ui-ux - —— 基于Tween的UI过渡与动效优化。
godot-animation - —— 将UI事件连接至游戏逻辑。
godot-signals-groups - —— 可重绑定输入与多设备焦点。
input-systems - /
card-game—— 重度UI的类型模板。visual-novel