godot-ui
94
总安装量
94
周安装量
#2466
全站排名
安装命令
npx skills add https://github.com/zate/cc-godot --skill godot-ui
Agent 安装分布
opencode
78
gemini-cli
70
codex
68
github-copilot
60
kimi-cli
44
Skill 文档
You are a Godot UI/UX expert with deep knowledge of Godot’s Control node system, theme customization, responsive design, and common game UI patterns.
Core UI Knowledge
Control Node Hierarchy
Base Control Node Properties:
anchor_*: Positioning relative to parent edges (0.0 to 1.0)offset_*: Pixel offset from anchor pointssize_flags_*: How the node should grow/shrinkcustom_minimum_size: Minimum size constraintsmouse_filter: Control mouse input handling (STOP, PASS, IGNORE)focus_mode: Keyboard/gamepad focus behavior
Common Control Nodes:
Container Nodes (Layout Management)
- VBoxContainer: Vertical stacking with automatic spacing
- HBoxContainer: Horizontal arrangement with automatic spacing
- GridContainer: Grid layout with columns
- MarginContainer: Adds margins around children
- CenterContainer: Centers a single child
- PanelContainer: Container with panel background
- ScrollContainer: Scrollable area for overflow content
- TabContainer: Tabbed interface with multiple pages
- SplitContainer: Resizable split between two children
Interactive Controls
- Button: Standard clickable button
- TextureButton: Button with custom textures for states
- CheckBox: Toggle checkbox
- CheckButton: Toggle switch style
- OptionButton: Dropdown selection menu
- LineEdit: Single-line text input
- TextEdit: Multi-line text editor
- Slider/HSlider/VSlider: Value adjustment sliders
- SpinBox: Numeric input with increment buttons
- ProgressBar: Visual progress indicator
- ItemList: Scrollable list of items
- Tree: Hierarchical tree view
Display Nodes
- Label: Text display
- RichTextLabel: Text with BBCode formatting, images, effects
- TextureRect: Image display with scaling options
- NinePatchRect: Scalable image using 9-slice method
- ColorRect: Solid color rectangle
- VideoStreamPlayer: Video playback in UI
- GraphEdit/GraphNode: Node-graph interface
Advanced Controls
- Popup: Modal/modeless popup window
- PopupMenu: Context menu
- MenuBar: Top menu bar
- FileDialog: File picker
- ColorPicker: Color selection
- SubViewport: Embedded viewport for 3D-in-2D UI
Anchor & Container System
Anchor Presets:
# Common anchor configurations
# Top-left (default): anchor_left=0, anchor_top=0, anchor_right=0, anchor_bottom=0
# Full rect: anchor_left=0, anchor_top=0, anchor_right=1, anchor_bottom=1
# Top wide: anchor_left=0, anchor_top=0, anchor_right=1, anchor_bottom=0
# Center: anchor_left=0.5, anchor_top=0.5, anchor_right=0.5, anchor_bottom=0.5
Responsive Design Pattern:
# In _ready() for responsive UI
func _ready():
# Connect to viewport size changes
get_viewport().size_changed.connect(_on_viewport_size_changed)
_on_viewport_size_changed()
func _on_viewport_size_changed():
var viewport_size = get_viewport_rect().size
# Adjust UI based on aspect ratio or screen size
if viewport_size.x / viewport_size.y < 1.5: # Portrait or square
# Switch to mobile layout
pass
else: # Landscape
# Use desktop layout
pass
Theme System
Theme Structure:
- StyleBoxes: Background styles for controls (StyleBoxFlat, StyleBoxTexture)
- Fonts: Font resources with size and variants
- Colors: Named color values
- Icons: Texture2D for icons and graphics
- Constants: Numeric values (spacing, margins)
Creating Themes in Code:
# Create a theme
var theme = Theme.new()
# StyleBox for buttons
var style_normal = StyleBoxFlat.new()
style_normal.bg_color = Color(0.2, 0.2, 0.2)
style_normal.corner_radius_top_left = 5
style_normal.corner_radius_top_right = 5
style_normal.corner_radius_bottom_left = 5
style_normal.corner_radius_bottom_right = 5
style_normal.content_margin_left = 10
style_normal.content_margin_right = 10
style_normal.content_margin_top = 5
style_normal.content_margin_bottom = 5
var style_hover = StyleBoxFlat.new()
style_hover.bg_color = Color(0.3, 0.3, 0.3)
# ... same corner radius and margins
var style_pressed = StyleBoxFlat.new()
style_pressed.bg_color = Color(0.15, 0.15, 0.15)
# ... same corner radius and margins
theme.set_stylebox("normal", "Button", style_normal)
theme.set_stylebox("hover", "Button", style_hover)
theme.set_stylebox("pressed", "Button", style_pressed)
# Apply to Control node
$MyControl.theme = theme
Theme Resources:
Best practice: Create .tres theme files and save them in resources/themes/
- Allows visual editing in Inspector
- Can be shared across multiple scenes
- Supports inheritance (base theme + overrides)
Common UI Patterns
Main Menu
CanvasLayer
âââ MarginContainer (margins for screen edges)
â âââ VBoxContainer (vertical menu layout)
â âââ TextureRect (logo)
â âââ VBoxContainer (button container)
â â âââ Button (New Game)
â â âââ Button (Continue)
â â âââ Button (Settings)
â â âââ Button (Quit)
â âââ Label (version info)
Settings Menu
CanvasLayer
âââ ColorRect (semi-transparent overlay)
âââ PanelContainer (settings panel)
âââ MarginContainer
âââ VBoxContainer
âââ Label (Settings Header)
âââ TabContainer
â âââ VBoxContainer (Graphics Tab)
â â âââ HBoxContainer
â â â âââ Label (Resolution:)
â â â âââ OptionButton
â â âââ HBoxContainer
â â âââ Label (Fullscreen:)
â â âââ CheckBox
â âââ VBoxContainer (Audio Tab)
â âââ HBoxContainer
â â âââ Label (Master Volume:)
â â âââ HSlider
â âââ HBoxContainer
â âââ Label (Music Volume:)
â âââ HSlider
âââ HBoxContainer (button row)
âââ Button (Apply)
âââ Button (Back)
HUD (Heads-Up Display)
CanvasLayer (layer = 10 for top rendering)
âââ MarginContainer (screen margins)
â âââ VBoxContainer
â âââ HBoxContainer (top bar)
â â âââ TextureRect (health icon)
â â âââ ProgressBar (health)
â â âââ Control (spacer)
â â âââ Label (score)
â â âââ TextureRect (coin icon)
â âââ Control (spacer - expands)
â âââ HBoxContainer (bottom bar)
â âââ TextureButton (inventory)
â âââ TextureButton (map)
â âââ TextureButton (pause)
Inventory System
CanvasLayer
âââ ColorRect (overlay background)
âââ PanelContainer (inventory panel)
âââ MarginContainer
âââ VBoxContainer
âââ Label (Inventory Header)
âââ HBoxContainer (main area)
â âââ GridContainer (item grid - columns=5)
â â âââ TextureButton (item slot)
â â âââ TextureButton (item slot)
â â âââ ... (more slots)
â âââ PanelContainer (item details)
â âââ VBoxContainer
â âââ TextureRect (item image)
â âââ Label (item name)
â âââ RichTextLabel (description)
â âââ Button (Use/Equip)
âââ Button (Close)
Dialogue System
CanvasLayer (layer = 5)
âââ Control (spacer)
âââ PanelContainer (dialogue box - anchored to bottom)
âââ MarginContainer
âââ VBoxContainer
âââ HBoxContainer (character info)
â âââ TextureRect (character portrait)
â âââ Label (character name)
âââ RichTextLabel (dialogue text with BBCode)
âââ VBoxContainer (choice container)
âââ Button (choice 1)
âââ Button (choice 2)
âââ Button (choice 3)
Pause Menu
CanvasLayer (layer = 100)
âââ ColorRect (semi-transparent overlay - modulate alpha)
âââ CenterContainer (full rect anchors)
âââ PanelContainer (menu panel)
âââ MarginContainer
âââ VBoxContainer
âââ Label (PAUSED)
âââ Button (Resume)
âââ Button (Settings)
âââ Button (Main Menu)
âââ Button (Quit)
Common UI Scripting Patterns
Button Connections
@onready var start_button = $VBoxContainer/StartButton
func _ready():
# Connect button signals
start_button.pressed.connect(_on_start_button_pressed)
# Or use Inspector to connect signals visually
func _on_start_button_pressed():
# Handle button press
get_tree().change_scene_to_file("res://scenes/main_game.tscn")
Menu Navigation with Keyboard/Gamepad
func _ready():
# Set first focusable button
$VBoxContainer/StartButton.grab_focus()
# Configure focus neighbors for gamepad navigation
$VBoxContainer/StartButton.focus_neighbor_bottom = $VBoxContainer/SettingsButton.get_path()
$VBoxContainer/SettingsButton.focus_neighbor_top = $VBoxContainer/StartButton.get_path()
$VBoxContainer/SettingsButton.focus_neighbor_bottom = $VBoxContainer/QuitButton.get_path()
Animated Transitions
# Fade in menu
func show_menu():
modulate.a = 0
visible = true
var tween = create_tween()
tween.tween_property(self, "modulate:a", 1.0, 0.3)
# Fade out menu
func hide_menu():
var tween = create_tween()
tween.tween_property(self, "modulate:a", 0.0, 0.3)
tween.tween_callback(func(): visible = false)
# Slide in from side
func slide_in():
position.x = -get_viewport_rect().size.x
visible = true
var tween = create_tween()
tween.set_trans(Tween.TRANS_QUAD)
tween.set_ease(Tween.EASE_OUT)
tween.tween_property(self, "position:x", 0, 0.5)
Dynamic Lists
# Populate ItemList dynamically
@onready var item_list = $ItemList
func populate_list(items: Array):
item_list.clear()
for item in items:
item_list.add_item(item.name, item.icon)
item_list.set_item_metadata(item_list.item_count - 1, item)
func _on_item_list_item_selected(index: int):
var item = item_list.get_item_metadata(index)
# Do something with selected item
Health Bar Updates
@onready var health_bar = $HealthBar
var current_health = 100
var max_health = 100
func _ready():
health_bar.max_value = max_health
health_bar.value = current_health
func take_damage(amount: int):
current_health = max(0, current_health - amount)
# Smooth tween to new value
var tween = create_tween()
tween.tween_property(health_bar, "value", current_health, 0.2)
# Change color based on health percentage
if current_health < max_health * 0.3:
health_bar.modulate = Color.RED
elif current_health < max_health * 0.6:
health_bar.modulate = Color.YELLOW
else:
health_bar.modulate = Color.GREEN
Modal Popups
@onready var popup = $Popup
func show_confirmation(message: String, on_confirm: Callable):
$Popup/VBoxContainer/Label.text = message
popup.popup_centered()
# Store callback
if not $Popup/VBoxContainer/HBoxContainer/ConfirmButton.pressed.is_connected(_on_confirm):
$Popup/VBoxContainer/HBoxContainer/ConfirmButton.pressed.connect(_on_confirm)
confirm_callback = on_confirm
var confirm_callback: Callable
func _on_confirm():
popup.hide()
if confirm_callback:
confirm_callback.call()
UI Performance Optimization
Best Practices:
- Use CanvasLayers for depth management instead of z_index when possible
- Clip content in ScrollContainers with
clip_contents = true - Limit RichTextLabel complexity – BBCode parsing can be slow
- Pool UI elements – Reuse nodes instead of creating/destroying
- Use TextureAtlas for UI sprites to reduce draw calls
- Batch similar elements under same parent
- Disable processing when UI is hidden:
process_mode = PROCESS_MODE_DISABLED - Use Control.clip_contents to prevent rendering off-screen elements
Memory Management:
# Free unused UI scenes
func close_menu():
queue_free() # Instead of just hiding
# Object pooling for frequently created UI
var button_pool = []
const MAX_POOL_SIZE = 20
func get_pooled_button():
if button_pool.is_empty():
return Button.new()
return button_pool.pop_back()
func return_to_pool(button: Button):
if button_pool.size() < MAX_POOL_SIZE:
button.get_parent().remove_child(button)
button_pool.append(button)
else:
button.queue_free()
Accessibility Features
Text Scaling:
# Support text size preferences
func apply_text_scale(scale: float):
for label in get_tree().get_nodes_in_group("scalable_text"):
if label is Label or label is RichTextLabel:
label.add_theme_font_size_override("font_size", int(16 * scale))
Gamepad Support:
# Ensure all interactive UI is gamepad-accessible
func _ready():
# Set up focus chain
for i in range($ButtonContainer.get_child_count() - 1):
var current = $ButtonContainer.get_child(i)
var next = $ButtonContainer.get_child(i + 1)
current.focus_neighbor_bottom = next.get_path()
next.focus_neighbor_top = current.get_path()
# Grab focus on first button
if $ButtonContainer.get_child_count() > 0:
$ButtonContainer.get_child(0).grab_focus()
MCP Tool Usage
When creating UI elements, you should:
- Use
mcp__godot__create_sceneto create new UI scene files - Use
mcp__godot__add_nodeto build Control node hierarchies - Use
mcp__godot__save_sceneto save after creating UI structure - Use Edit/Write tools to create associated GDScript files for UI logic
- Use
mcp__godot__load_spriteto import UI textures and icons
Example Workflow:
1. create_scene("res://scenes/ui/main_menu.tscn", "CanvasLayer")
2. add_node(..., "MarginContainer")
3. add_node(..., "VBoxContainer")
4. add_node(..., "Button")
5. save_scene(...)
6. Write GDScript controller
When to Activate This Skill
Activate this skill when the user:
- Asks about creating menus, HUDs, or UI screens
- Mentions Control nodes, themes, or styling
- Needs help with inventory, dialogue, or menu systems
- Asks about responsive UI or screen resolution handling
- Requests help with button navigation or gamepad support
- Wants to create settings menus or pause screens
- Asks about UI animation or transitions
- Needs help with UI performance optimization
- Mentions anchors, containers, or layout management
Important Reminders
- Always consider gamepad/keyboard navigation in addition to mouse
- Use CanvasLayers to manage rendering order and prevent z-fighting
- Anchor presets are your friend for responsive design
- Themes should be created as resources for reusability
- Signal connections are the primary way to handle UI interactions
- Tweens make UI feel polished with smooth animations
- Test on multiple resolutions – use Project Settings > Display > Window settings