mcpField
G
game-ui-ux

game-ui-ux

github.com/gamedev-skills设计与 UI5.4k10.5k 次安装1 天前更新
代码仓库

关于 game-ui-ux

game-ui-ux 是一项与引擎无关的技能,用于设计适配不同屏幕尺寸和输入设备的游戏 HUD、菜单与覆盖层。重点包括响应式布局、焦点导航、屏幕栈和事件驱动的 UI 更新。

主要功能

  1. 01响应式锚点与容器布局
  2. 02参考分辨率缩放
  3. 03适配安全区域的布局
  4. 04键盘与手柄焦点导航
  5. 05基于栈的屏幕流程
  6. 06事件驱动的 HUD 更新

适用场景

  1. 01构建适配多种屏幕的 HUD
  2. 02让菜单支持手柄导航
  3. 03组织暂停与设置界面
  4. 04根据游戏事件更新 HUD

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill game-ui-ux

安装后在 Claude Code 中输入/game-ui-ux确认已加载。

附带文件references/layout-and-flow.md

详细介绍

游戏 UI/UX

构建 HUD 和菜单,让它们在手机、超宽屏显示器和电视上都能正确显示,并支持手柄和鼠标操作。本技能负责与引擎无关的 UI 架构——响应式布局、缩放、焦点导航、屏幕流程,以及 UI 与游戏状态的交互方式;具体的控件 API 则交由引擎 UI 技能负责。

何时使用

  • 构建 HUD(生命值/弹药/分数)、菜单(主菜单/暂停/设置)、背包或商店界面,或任何叠加界面,并希望它们能正确缩放和导航时。
  • 修复在其他分辨率/宽高比下显示异常、忽略刘海/安全区域、无法使用控制器操作,或通过逐帧轮询与游戏状态连接的 UI 时。
  • 将屏幕流程(标题 → 游戏 → 暂停 → 设置)组织为堆栈,而不是一团布尔标志时。

**何时不使用:**对于引擎的具体 UI 节点/组件和样式,请使用 godot-ui-control 或 Unity UI(UGUI/UI Toolkit)。对于视觉冲击效果(按钮弹跳、伤害数字、震动),请使用 game-feel。对于分支对话 UI,请使用 dialogue-systems。翻译 UI 字符串属于本地化(重绑定界面请参阅 references/ 和 input-systems)。对于卡牌/棋盘布局的具体需求,card-game 类型会组合使用本技能。

核心工作流

  1. **选择布局模型:锚点 + 容器,绝不使用绝对像素。**将元素锚定到边缘/角落/中心,并让容器(行、列、网格)排列子项。绝对 (x, y) 坐标在遇到第一个新分辨率时就会出问题。
  2. 为整个 UI 选择缩放策略:使用一个可缩放以适应屏幕的参考分辨率(适用于大多数游戏),再制定其他宽高比下额外宽度/高度的处理策略(加黑边、扩展,或将 HUD 角落向外锚定)。
  3. **遵循安全区域。**让关键 UI 与屏幕边缘保持一定距离,避免刘海、圆角和电视过扫描将其裁切。
  4. **确保每个屏幕都能通过键盘/手柄导航。**为每个屏幕设置初始焦点控件,定义焦点顺序/邻接关系,并清晰显示焦点高亮。鼠标和焦点导航必须能共存。
  5. **将屏幕建模为堆栈。**压入新屏幕(在游戏上方显示暂停界面)、弹出屏幕(恢复游戏),并将输入权限与可见性交给顶层屏幕。这样叠加界面和“返回”操作都很简单。
  6. **通过事件驱动 HUD,而不是轮询。**HUD 订阅 health_changed、score_changed 等事件,并仅在事件触发时更新,而不是每帧读取游戏状态。
  7. **在不同屏幕和设备上验证。**调整窗口大小、切换宽高比、拔掉鼠标后仅用手柄导航,并确认焦点、缩放和安全区域边距。报告你在各个分辨率下实际观察到的情况。

模式

1. 使用锚点 + 容器,而不是绝对坐标
# Godot 4.7. Anchor a HUD label to the TOP-LEFT; let a container flow a row of hearts.
func _ready() -> void:
    $Score.set_anchors_preset(Control.PRESET_TOP_LEFT)   # sticks to the corner at any size
    # An HBoxContainer auto-lays-out children left-to-right; never position hearts by hand.
    for i in lives:
        $Hearts.add_child(make_heart())                   # HBoxContainer spaces them for you
# Unity 6.3 LTS uGUI: set RectTransform anchors to the corner; use a HorizontalLayoutGroup.
# RIGHT: anchors + layout groups. WRONG: rect.anchoredPosition = new Vector2(640, 360) (1080p-only).
2. 缩放至参考分辨率(一个 UI,适配多个屏幕)
# Godot 4.7 — Project Settings > Display > Window > Stretch:
#   Mode = "canvas_items", Aspect = "expand", reference size e.g. 1920x1080.
#   UI scales to the window; "expand" reveals extra space you anchor HUD corners into.
# Unity 6.3 LTS — Canvas > CanvasScaler:
#   UI Scale Mode = "Scale With Screen Size", Reference Resolution = 1920x1080,
#   Match = 0.5 (blend width/height) — pick 1.0 if your HUD is height-critical.
3. 为刘海/过扫描设置安全区域边距
# Godot 4.7. Inset a margin container to the OS-reported safe rect (phones, TVs).
func _apply_safe_area() -> void:
    var safe: Rect2i = DisplayServer.get_display_safe_area()
    var win := DisplayServer.window_get_size()
    $Margin.add_theme_constant_override("margin_left", safe.position.x)
    $Margin.add_theme_constant_override("margin_top",  safe.position.y)
    $Margin.add_theme_constant_override("margin_right", win.x - safe.end.x)
    $Margin.add_theme_constant_override("margin_bottom", win.y - safe.end.y)
# Unity 6.3 LTS: read Screen.safeArea (Rect in pixels) and set a panel's anchorMin/anchorMax to
# safeArea.position / (position+size) normalized by Screen.width/height.
4. 手柄/键盘焦点(没有焦点导航,控制器就无法操作 UI)
# Godot 4.7. Give each screen a default focus and wire neighbors so a stick/d-pad walks it.
func _on_screen_shown() -> void:
    $PlayButton.grab_focus()                               # always focus SOMETHING on open
$PlayButton.focus_neighbor_bottom = $SettingsButton.get_path()
$SettingsButton.focus_neighbor_top = $PlayButton.get_path()
# Unity 6.3 LTS: EventSystem.SetSelectedGameObject(playButton) on enable; set each Selectable's
# Navigation (Explicit or Automatic). RIGHT: a control is focused on open. WRONG: nothing
# selected → the gamepad does nothing and the player is stuck.
5. 事件驱动 HUD(让 UI 与游戏逻辑解耦)
# RIGHT: HUD reacts to a signal; it updates only when health actually changes.
func _ready() -> void:
    player.health_changed.connect(_on_health_changed)     # emitted by gameplay
func _on_health_changed(current: int, max: int) -> void:
    $HealthBar.value = float(current) / max
# WRONG: func _process(dt): $HealthBar.value = player.hp / player.max_hp  # polls every frame,
# couples UI to the player's internals, and runs work even when nothing changed.

常见问题

  • 绝对像素位置/单一设计分辨率。 在你的显示器上看起来没问题,在其他地方却会出错。应锚定到边缘或中心,并随容器布局。
  • 没有纵横比策略。 仅适用于 16:9 的布局在超宽屏和手机上会严重裁切或出现黑边。决定是扩展还是加黑边,并将 HUD 锚定到会向外移动的角落。
  • 忽略安全区域。 HUD 被刘海遮挡,或被电视过扫描裁掉。将关键元素向内缩进。
  • 没有初始焦点/没有焦点邻居。 游戏手柄无法正常操作游戏;玩家进入菜单时没有任何选项被选中。始终让一个控件获得焦点,并定义导航方式。
  • 在 _process/Update 中轮询游戏状态。 这会让 UI 与内部实现紧密耦合,并浪费资源。通过信号/事件推送更新。
  • 固定字号太小。 在远距离观看的电视或小屏手机上难以阅读。让文字随 UI 缩放,并提供字号选项。
  • 用布尔标志管理菜单流程(isPaused、inSettings 等)会变得难以管理。使用可推入/弹出的屏幕栈。
  • 将硬编码的英文字符串写入布局。 翻译后的文字会溢出按钮。将字符串外置,并让容器根据内容调整尺寸(参见 references/)。
  • 仅支持鼠标或仅支持焦点操作。 两者都要支持;切换输入设备时不应让用户陷入困境。

参考资料

  • 有关各引擎的拉伸/缩放模式、安全区域计算、完整的焦点导航与屏幕栈模式、沉浸式与非沉浸式 UI、无障碍功能(字号、对比度、适合色盲用户的状态显示),以及支持本地化的布局,请阅读 references/layout-and-flow.md。

相关技能

  • godot-ui-control、Unity UI(UGUI/UI Toolkit)——具体的控件、主题和样式。
  • game-feel ——按钮弹跳、过渡效果,以及叠加在此布局之上的 HUD 活力效果。
  • dialogue-systems ——构建在此 UI 外壳中的对话/选项 UI。
  • input-systems ——设备切换、按键重绑定界面和无障碍控件。
  • rpg、card-game、tower-defense、visual-novel ——适合组合使用此技能的重 UI 类型游戏。

评论

支持 Markdown