彈出層、對話框、底部頁面、卡片、HUD 面板、行內提示與浮動訊息,它們的面都畫在 80% 不透明度上。 確認對話框後面的戰鬥還在打;庫存頁面底下的地圖還看得見。在遊戲裡這不是裝飾 — 是它讓玩家知道自己在哪裡。 完全不透明的面板,會在視窗打開的那一瞬間抹掉玩家原本站的地方。
只有面變淡。文字、圖示、按鈕、徽章與快捷格都保持清晰,邊框與陰影也是。
半透明的面板,只有在輪廓俐落時才讀得出玻璃感;輪廓一淡,就分不出面板到哪裡結束。
內容一淡,介面根本讀不了 — 那不是透明視窗,那是 bug。這就是為什麼這個值從來不透過
modulate.a 套用。
五層,由最明確的開始
| 順序 | 在哪裡 | 單位 | 影響範圍 |
|---|---|---|---|
| ① | 那次呼叫傳進去的參數 — surface.alpha、GoStyle.card(…, alpha) | 比例 0.0–1.0 | 一個視窗 |
| ② | GoConfig.container_alpha_overrides[kind] | 比例 0.0–1.0 | 某一類面板,整個專案都算 |
| ③ | GoConfig.metric_overrides[<kind>_alpha] | 百分比 | 把所有尺寸集中放在一處的專案 |
| ④ | GoConfig.container_alpha | 比例 0.0–1.0 | 一次套到所有面板 |
| ⑤ | 佈景主題的 GoHud/constants/<kind>_alpha | 百分比 | 這套外觀自己的決定 — 最終依據 |
五層都沒設定時,值就是 100,所以舊佈景主題不會有任何改變。
不透明度到處都是比例 — 只有佈景主題例外。每個
alpha 欄位與參數收的都是
0.0–1.0,跟 Color.a、modulate.a 同一套單位,負值表示「沒設定」。
唯一的例外是佈景主題的常數,因為 Theme 常數存不了浮點數:它們,以及覆寫它們的那條管道
(metric_overrides,它沿用佈景主題的名稱與整數型別),寫成 80。
其他地方都不是。
# 只影響一個視窗 — 確認對話框不該擋住後面的戰鬥
surface.alpha = 0.6
sheet.alpha = 0.7
dialogs.alpha = 0.9 # @export 欄位也是比例
drawer.alpha = 0.7
GoPopover.open(slot, body, {"alpha": 0.9})
var glass := GoStyle.card(Color.TRANSPARENT, -1.0, -1.0, -1.0, 0.5)
# 依類別 — HUD 保持幾乎不透明,因為它的文字直接疊在世界上
GoUi.config.container_alpha_overrides = {
GoTheme.BOX_PANEL: 0.7, # 對話框與底部頁面可以透一點
GoTheme.BOX_HUD: 0.95,
}
GoUi.refresh() # 重畫已經開著的控制項
# 整個專案 — 畫面很忙的世界會想把面板調回不透明
GoUi.config.container_alpha = 1.0
GoUi.refresh()
GoUi.surface_alpha(GoTheme.BOX_PANEL) # 算好的比例,例如 0.8
哪些跟著這個值走,哪些不跟
| 跟著走 — 容器 | 不跟 — 會去按的東西,以及標記 |
|---|---|
GoSurface(對話框、底部頁面與下拉選單共用的那層外殼)· GoSheet · GoDialogs · GoDrawer · GoPopover · GoNotice · GoSnackbar · GoPromptCard · GoCoachMark · GoConsole |
所有按鈕 · GoSlot(快捷格)· GoBadge · 分段控制項 · 選項儲存格 · 標籤片 · 圓底與頭像 |
GoStyle.card() · hud_panel() · overlay_panel() · alert() · plate() · edge_card_panel() · style_notice_panel() · floating() · box() · surface() |
所有文字與圖示 |
狀態被沖淡的按鈕,說不清自己現在是什麼;而徽章存在的理由,就是讓兩個字看得清楚 — 兩者都不是容器,所以都不跟著這個值走。
彈出選單保持不透明(
popup_alpha 100)。引擎可能把
PopupMenu 放進它自己的 Window,在那裡作業系統不會把它和遊戲合成:
半透明出來是黑的,而不是透出背後。只有在把子視窗內嵌起來的專案
(gui_embed_subwindows)裡才調低它。
三個從實際畫面上得來的細節
-
這個值是相乘,不是取代。預設 HUD 的面本來就是 0.92 alpha,所以
hud_alpha80 落在 0.736 — 刻意把某個面做成半透明的佈景主題,那個決定會留著。 反過來說:套兩次,面板就淡兩次,所以 alpha 只在唯一一個地方相乘 (GoSkin.surface_box()),其他每個畫面的函式都只是把參數往下傳, 而不是去淡化自己的結果。 -
你傳進去什麼顏色,拿到的就是什麼顏色。
GoStyle.plate(…, fill)會原封不動地保留明確給定的填色:Color(ink, 0.14)已經把自己的 alpha 講清楚了, 再把面板不透明度乘進去,等於把呼叫端的意圖砍了兩次。基於同一類理由,GoStyle.floating(…, opaque = true)也忽略這個值 — 把面填滿本來就是那個旗標的全部目的。 -
不是 gohud 做的面板,適用同一條規則。
GoStyle.fade_panel(node)— 要在節點進到樹裡之後呼叫,這樣它才讀得到繼承來的佈景主題。它是冪等的: 原本的面會被記下來,每次呼叫都從那裡重算,所以重畫再多次也不會疊加。 換過佈景主題之後,GoStyle.forget_face(node)會丟掉那份記憶, 下一次呼叫才拿得到新的面。
自訂的面也會變淡 — 而這正是會默默壞掉的地方
斜切角的面板(GoStyleBoxCut)與鍛造框(GoStyleBoxMedieval)
不是 StyleBoxFlat,它們自己畫自己。把不透明度只寫進 flat 那條分支,
這兩套佈景主題就會默默忽略它,而所有看數值的測試照樣通過。兩者都會淡化自己的背景,
同時把光暈、鉚釘、角落雕刻與斜角維持在滿強度 — 而中世紀面的紋理與斜角本來就和它的背景
alpha 成正比,所以會跟著面板一起變淡。
說到底是這麼一回事:bg_color.a == 0.8 是一個數字。世界透得出來,
而文字依然讀得清楚才是要求。gohud 用無頭測試套件檢查前者,用虛擬螢幕把面板畫在
斜線條紋上檢查後者(tests/gohud_alpha_shot.gd)— 平面、斜切與鍛造三種面都測,
深色與淺色佈景主題也都測。