Godot Ui

zate/cc-godot/plugins/gd/skills/godot-ui

作者 zated9796f75c3f5無授權條款18 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫11 個月前更新

Expert knowledge of Godot's UI system including Control nodes, themes, styling, responsive layouts, and common UI patterns for menus, HUDs, inventories, and dialogue systems. Use when working with Godot UI/menu creation or styling.

AI 產生的概覽

使用 Control 節點、主題、版面配置,以及常見選單、HUD、背包與對話模式來建構 Godot 遊戲介面的參考指南。

功能
此技能提供 Godot UI 系統的專家參考資料:Control 節點階層、容器、錨點、主題與 StyleBox 系統,以及響應式版面配置技巧。它記錄常見的遊戲介面模式,例如主選單、設定畫面、HUD、背包、對話框與暫停選單,並附上用於訊號、焦點導覽、補間動畫、動態清單、血條與模態彈出視窗的 GDScript 程式碼片段。它也涵蓋 UI 效能最佳化、無障礙與遊戲手把支援,並建議採用基於 MCP 的工作流程來建立場景與節點。
適用情境
在建立或美化 Godot 選單、HUD 或其他介面,或處理 Control 節點、主題、錨點與容器時使用。它也適合關於背包、對話或設定介面、響應式版面配置、遊戲手把與鍵盤導覽、UI 動畫或 UI 效能的問題。
執行需求
僅為說明性內容,不隨附指令碼。它假定已有 Godot 專案,且就所述的場景建構工作流程而言,需要 Godot MCP 工具以及檔案讀取、寫入、編輯、glob 與 grep 權限。

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 points
  • size_flags_*: How the node should grow/shrink
  • custom_minimum_size: Minimum size constraints
  • mouse_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:

gdscript
# 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:

gdscript
# In _ready() for responsive UIfunc _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:

gdscript
# Create a themevar theme = Theme.new()
# StyleBox for buttonsvar style_normal = StyleBoxFlat.new()style_normal.bg_color = Color(0.2, 0.2, 0.2)style_normal.corner_radius_top_left = 5style_normal.corner_radius_top_right = 5style_normal.corner_radius_bottom_left = 5style_normal.corner_radius_bottom_right = 5style_normal.content_margin_left = 10style_normal.content_margin_right = 10style_normal.content_margin_top = 5style_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

gdscript
@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

gdscript
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

gdscript
# Fade in menufunc show_menu():    modulate.a = 0    visible = true    var tween = create_tween()    tween.tween_property(self, "modulate:a", 1.0, 0.3)
# Fade out menufunc 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 sidefunc 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

gdscript
# 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

gdscript
@onready var health_bar = $HealthBarvar current_health = 100var 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

gdscript
@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:

  1. Use CanvasLayers for depth management instead of z_index when possible
  2. Clip content in ScrollContainers with clip_contents = true
  3. Limit RichTextLabel complexity - BBCode parsing can be slow
  4. Pool UI elements - Reuse nodes instead of creating/destroying
  5. Use TextureAtlas for UI sprites to reduce draw calls
  6. Batch similar elements under same parent
  7. Disable processing when UI is hidden: process_mode = PROCESS_MODE_DISABLED
  8. Use Control.clip_contents to prevent rendering off-screen elements

Memory Management:

gdscript
# Free unused UI scenesfunc close_menu():    queue_free()  # Instead of just hiding
# Object pooling for frequently created UIvar 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:

gdscript
# Support text size preferencesfunc 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:

gdscript
# Ensure all interactive UI is gamepad-accessiblefunc _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:

  1. Use mcp__godot__create_scene to create new UI scene files
  2. Use mcp__godot__add_node to build Control node hierarchies
  3. Use mcp__godot__save_scene to save after creating UI structure
  4. Use Edit/Write tools to create associated GDScript files for UI logic
  5. Use mcp__godot__load_sprite to 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

來源與署名

來源:zate/cc-godot位於plugins/gd/skills/godot-ui提交d9796f7

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架