G

godot-ui

by @zatev
4.3(20)

Godot UI/UXの専門家で、Controlノードシステム、テーマカスタマイズ、レスポンシブデザイン、一般的なゲームUIパターンに精通しています。

godot-engineui/ux-designgame-interfacegdscriptscene-managementGitHub
インストール方法
npx skills add zate/cc-godot --skill godot-ui
compare_arrows

Before / After 効果比較

1
使用前

GodotでゲームUIをデザインする際、インターフェースのレイアウトが複雑で、様々な画面サイズに対応しにくい。ユーザーエクスペリエンスが低く、ゲームの魅力に影響を与えます。

使用後

Godot UI/UXの専門知識を活用し、応答性が高く美しいインターフェースを実現。ゲームのユーザーエクスペリエンスを大幅に向上させ、プレイヤーの没入感を高めます。

SKILL.md

godot-ui

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:

# 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_scene to create new UI scene files

  • Use mcp__godot__add_node to build Control node hierarchies

  • Use mcp__godot__save_scene to save after creating UI structure

  • Use Edit/Write tools to create associated GDScript files for UI logic

  • 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 sh

...

ユーザーレビュー (0)

レビューを書く

効果
使いやすさ
ドキュメント
互換性

レビューなし

統計データ

インストール数1.2K
評価4.3 / 5.0
バージョン
更新日2026年5月21日
比較事例1 件

ユーザー評価

4.3(20)
5
20%
4
50%
3
25%
2
5%
1
0%

この Skill を評価

0.0

対応プラットフォーム

🔧Claude Code
🔧OpenClaw
🔧OpenCode
🔧Codex
🔧Gemini CLI
🔧GitHub Copilot
🔧Amp
🔧Kimi CLI

タイムライン

作成2026年3月17日
最終更新2026年5月21日