gohud

游戏 UI,用一份资源驱动

gohud 是面向 Godot 4.6 及以上版本的 HUD 与 UI 套件。浮动窗口、底部面板、对话框、表单、 消息条、引导标记、HUD 状态条、快捷槽和虚拟摇杆全都由一份主题和一份可替换的图标集驱动, 安全区域、虚拟键盘、RTL 和触摸目标都替你处理好。 六套预设 —— 默认、科幻和中世纪,每种各有深色与浅色 —— 一行代码就能换掉颜色和形状。

Godot 4.6+ v1.0.1 纯 GDScript 无需自动加载 MIT 6 套预设 21 种语言 内置 100 个图标

放进游戏里是什么样子

中世纪和科幻预设 —— 角色面板、背包和任务;表单、网格和提示卡片;棱角分明的面板与触摸操控。 切换预设只要一行代码。

gohud 中世纪主题 —— 带生命、魔法和耐力条的角色面板,装满快捷槽的行囊,以及锻造金框的任务日志
中世纪 —— 角色、背包与任务
gohud 中世纪主题 —— 含姓名输入框、开关、复选框和音量滑块的输入面板,方块网格,以及带接受和拒绝的组队邀请提示卡片
中世纪 —— 表单、网格与提示卡片
gohud 科幻主题 —— 切角的触摸操控面板,配六边形摇杆、固定 / 跟随 / 相对切换开关和圆形动作按钮
科幻 —— 棱角面板与触摸操控

全部六套预设以及切换方法 →

它替你接手了什么

游戏 UI 最费时间的从来不是按钮长什么样,而是那些会在各种设备之间慢慢跑偏的东西。 gohud 把这些偏差集中到一处处理。

每个尺寸都是一个令牌

间距、圆角和字号都按名字取用,而不是写死数字。换掉主题,整个画面跟着一起变。

看得见的大小 ≠ 按得到的大小

关闭按钮看上去是 36dp,触摸目标却有 48dp。密集的快捷槽互相重叠时,中心更近的那个接住这次点按。

刘海与键盘

HUD 各部件待在安全区域之内,虚拟键盘弹出时输入框会抬到键盘上方。

返回只关掉一层

Esc 和安卓返回键只关闭最上面那一层。叠起来的窗口不会一起消失。

提示条从不抢走输入

隔着消息条按下去,底下的按钮照样收到。焦点也不会被夺走。

图标按名字取用

控件只认识 GoIconSet.CLOSE。换掉图标集,所有画法随之改变,一行代码都不用动。

六种外观,一行代码

GoUi.use_preset() 把主题、皮肤和图标一起换掉 —— 圆角、科幻切角,或是锻造的中世纪边框。

可读性靠量出来

每套主题都对照 WCAG 检查过,连按钮的各种状态和盖在纯白、纯黑之上的半透明 HUD 面板也不例外。

不启用插件也照样能用。 启用之后会多一个 GoRuntime 自动加载节点,用来跟踪窗口尺寸、dp 缩放和键盘高度, 再加上配置资源和预设的项目设置项 —— 这些是方便,不是必需。

安装 gohud

两条路:让 AI 代理替你装,或把文件夹放进项目 —— 此外无需任何配置。

安装

快速上手

五行代码就能显示一个带主题的界面。完整流程见安装页。

快速上手

换外观 —— 换颜色,换形状

Theme 只能改引擎自己绘制的那部分。StyleBoxFlat 只有圆角这一种角,而摇杆、快捷槽和引导标记是用代码画的 —— 所以光靠主题永远改不了它们的形状。为此 gohud 提供了预设:把一份主题、一份皮肤和一份图标集打包成一个整体。

GoUi.use_preset(GoThemePresets.MEDIEVAL_DARK)   # 主题、皮肤和图标一起换
预设外观
default_darkgohud 的原始外观 —— 圆角,柔和的蓝色强调色
default_light同样的形状,换成浅色调色板
scifi_dark切角、青色霓虹边与辉光、六边形摇杆、瞄准框
scifi_light同样的棱角形状,用明亮的蓝图配色
medieval_dark暗铁与皮革、仿古金边框、铆钉、雕刻图标、Cinzel 标题字体
medieval_light羊皮纸、墨水与青铜,配同样的锻造边框
使用 default_dark 预设的 gohud 控件画廊 —— 圆角与蓝色强调色
default_dark —— 圆角,柔和的蓝色强调色
default_light 预设 —— 同样的形状换成浅色调色板
default_light —— 形状不变,浅色调色板
scifi_dark 预设 —— 切角与青色霓虹
scifi_dark —— 切角,青色霓虹
scifi_light 预设 —— 同样的棱角形状换成蓝图配色
scifi_light —— 棱角依旧,蓝图配色

这四张是同一个画廊界面。代码一行都没差,只换了预设名字。 按钮圆角、开关形状、列表行和输入框边框全都跟着一起变。

中世纪合集

medieval_dark 把铁与皮革配上仿古金;medieval_light 用羊皮纸和墨水。 菜单边框带一颗铆钉和小小的角落纹饰,而常驻显示的 HUD 保持素净; 16 个雕刻图标重画了对应的物品名,只有标题和副标题使用随包附带的 Cinzel 字体。

medieval_dark —— 角色面板、装满快捷槽的行囊和任务日志
medieval_dark —— 铁与皮革
medieval_light —— 同样的角色、行囊和任务界面,换成羊皮纸质感
medieval_light —— 羊皮纸与墨水

两张图都出自 examples/medieval/medieval.tscn,全部由标准控件搭成。 中世纪指南,以及如何造一个自己的王国 →

同一个界面,在手机上和在桌面上

画廊截图是竖屏手机。下面是同一份代码在 1280×800 下的样子 —— 内容停在便于阅读的宽度(480dp)并居中, HUD 仍待在四角。表单会绕开浮动的 HUD 部件,但本来就没挡住时不会移动: 在宽屏上硬推一把,只会让内容偏离中心。

1280x800 下的 default_dark —— 内容居中,HUD 在四角
default_dark · 1280×800
1280x800 下的 scifi_dark —— 同样的布局,换成切角面板与霓虹
scifi_dark · 1280×800

同一个面板,不同的外观

default_dark 下的底部面板
默认 —— 圆角卡片,常驻搜索行与底栏
scifi_dark 下的底部面板 —— 顶边有霓虹强调线
科幻 —— 顶部强调边、切角、辉光

项目设置 → gohud → Theme → Preset 里挑一套,或者设置 GoConfig.preset。 显式填写 themeskinicons压过预设, 所以你可以在一套预设的基础上只覆盖其中一项。

一套新主题就是一个 JSON 文件。 new_theme.py kingdom --from medieval_dark 会写出一份把所有继承值都列全的调色板;make_theme.py kingdom 生成主题、控件贴图和皮肤旋钮, 随后这套预设就会出现在选择器里。全部设置项与旋钮 →

皮肤 —— Theme 够不着的地方

皮肤管着摇杆、快捷槽的面、引导标记的光圈、标签片、骨架屏、内联提醒、分隔线和分节标题。 继承它,只重写你想改的部分。

class_name MySkin extends GoSkin

func slot_box(accent: Color, lit: bool) -> StyleBox:
    var box := GoStyleBoxCut.new()
    box.bg_color = accent
    box.cut = 6.0
    box.edge_color = accent
    return box
能画出的形状
GoStyleBoxCut斜切的角(切角)、一条加粗的强调边、外发光
GoStyleBoxBracket只画四角的标记,不把内容围起来
GoStyleBoxMedieval锻造边框,带铆钉、角落雕花、斜面高光和材质纹理

三者都能序列化进 Theme 资源 —— 正是这一点让主题不只能换颜色,还能换形状GoSkinSciFiGoSkinMedieval 是随包提供的子类。

GoStyle.box() 永远返回 StyleBoxFlat,因为调用方拿到它之后 还要调整 bg_colorcorner_radius。需要保住自定义形状时, 请改用 GoStyle.surface()

控件

全部部件,一张表看完。逐个细讲 →

基类作用
GoSurfaceControl浮动卡片外壳 —— 居中、靠底或贴着控件摆放,常驻页眉页脚,滚动主体,可拖动改变大小
GoSheetCanvasLayer从底部升起的页面,位于自己的图层上,因此始终盖在 HUD 之上
GoDialogsNode可以 await 的确认框和提醒框;不可逆的操作用 destructive
GoFormMarginContainer限定最大宽度的表单,会避开虚拟键盘,配合 avoid_hud 还会避开 HUD
GoScrollScrollContainer触摸滚动;滚动条收进卡片自带的内边距里
GoNoticePanelContainer既不吃输入也不抢焦点的消息条
GoPromptCardPanelContainer不打断游戏的提问卡片
GoCoachMarkControl指向真实控件的新手引导;按下目标本身就能推进
GoHudAnchorControl把 HUD 部件钉在安全区域的九个位置之一
GoBarControl生命、魔法和经验条,数值变化带缓动
GoSlotButton一个快捷槽 —— 图标、数量、冷却和快捷键都在同一个面上
GoJoystickControl固定、跟随或相对模式的虚拟摇杆
GoIconButtonButton看着小,按着大
GoStylestatic按钮、列表行、输入框、标签片、表格、标签页等等,都用同一种方式造出来

等待、告知、计数

基类作用
GoSnackbarNodeGoSnackbar —— 会自己找位置的消息条
GoSpinnerControlGoSpinner —— 看不到尽头的等待
GoBadgePanelContainerGoBadge —— 未读的小圆点、NEW 角标、99+

表单与列表

基类作用
GoFieldVBoxContainerGoField —— 会出错的那一行
GoInputGroupHBoxContainerGoInputGroup —— 和按钮焊在一起的输入框
GoComboboxButtonGoCombobox —— 能搜索的选择器
GoCodeInputVBoxContainerGoCodeInput —— 兑换码和礼品码
GoTableVBoxContainerGoTable —— 可排序的表头、可选中的行
GoPaginationHBoxContainerGoPagination —— 页码,或者一行“更多”

游戏真正用得上的形态

基类作用
GoRewardCalendarVBoxContainerGoRewardCalendar —— 每日签到
GoRadar · GoDonutControlGoRadar 和 GoDonut —— 一眼看完的属性
GoCarouselVBoxContainerGoCarousel —— 横幅和角色选择
GoKbdHBoxContainerGoKbd —— 不会骗人的按键提示

盖在屏幕之上

基类作用
GoDrawerCanvasLayerGoDrawer —— 侧边抽屉
GoPopoverRefCountedGoPopover —— 贴着控件的卡片
GoContextMenuRefCountedGoContextMenu —— 长按与右键
GoConsoleCanvasLayerGoConsole —— 开发者控制台

AI SKILL

gohud 自带 AI 技能:完整 API、可直接运行的模板和预览启动器。把下面这一段粘贴给你的编码代理,它就会装好 gohud 并知道怎么用。

AI SKILL

可读性是量出来的,不是看出来的

“好看”是口味问题;“看得清”却可以测量。 灰得发淡的文字在好显示器上没问题, 到了白天的手机屏上就消失了 —— 靠眼睛挑颜色,迟早会出这种事。

python3 addons/gohud/tools/check_contrast.py

六套主题里的每一对颜色,以及每个按钮状态下的文字与它所在的面板,都会拿去对照 WCAG 测量。 半透明颜色会先与真实背景合成再测 —— 直接测半透明色,得到的比值会比屏幕上实际看到的更好看。

因此文字颜色是推导出来的,而不是挑出来的:生成器以调色板里的值为起点,不断推高它的明度, 直到它在每一个可能落脚的面上都达标为止。改了调色板,对比度会自动跟上。 这些规则以及背后的坑 →

检查、发布与这个网站

一个入口跑完所有检查;每一部分都能发现其他部分看不到的问题。

bash addons/gohud/tools/check_all.sh
检查能抓到什么
四种屏幕尺寸下的 run_tests.sh控件行为与布局、RTL 下的位置、键盘焦点、运行时皮肤对比度、全部预设
new_project_check.sh对宿主项目的隐藏依赖;加 --zip 检查实际发布的压缩包,加 --export 检查 Web 构建
check_contrast.py每个主题文件的 WCAG 对比度,含按钮各状态与半透明面板
check_generated.py · check_scaffold.sh生成的主题与其调色板一致;临时主题能成功生成并通过对比度检查
check_package.py采用 package.json 的版本号、变更日志的搬移和 ZIP 内容,全部在临时副本中验证
check_site.py本站的链接、锚点、页面语言、术语表和旋钮表格
最近一次记录在案的运行 —— 2026-09-13,Godot 4.7.2,macOS,Compatibility 渲染器。 在空项目中于 390×844、844×390、768×1024 和 1280×800 下 438 项检查全部通过;加上 GoRuntime 自动加载后再次 438 项全过; 完成一次 Web 导出;六套主题对比度零失败。这一轮没有覆盖 Godot 4.6,也没有覆盖 Android 或 iOS 真机。

发布版本

cat addons/gohud/package.json       # { "version": "1.1.0" }
bash addons/gohud/tools/package.sh  # 1.1.0 → builds/1.1.0/gohud-1.1.0.zip

版本号就是 package.json 里写的那个,打包绝不会自动递增。 要发布新版本,先改这个数字。 运行成功会把 plugin.cfgGoUi.VERSION 设为该版本,并且只在该版本第一次打包时,把 CHANGELOG.md 中 Unreleased 下的记录挪进带日期的条目。 同一版本再次打包会重新生成 ZIP 并替换旧的。运行失败则什么都不改。 ZIP 里不包含这个网站、测试、工具和 package.json

这个网站

python3 addons/gohud/tools/make_site.py            # 术语表和皮肤旋钮表格,直接从源码生成
python3 addons/gohud/tools/check_site.py           # 检查链接、锚点、语言、术语表和生成的表格
bash addons/gohud/tools/site_shots.sh /tmp/shots   # 为每个页面截取桌面版和手机版截图

这些页面就是 www/ 下的普通 HTML —— 根目录是英文,ko/ 是韩文。 一个 GitHub Actions 工作流把那个文件夹作为站点根目录发布出去。