一個 HUD 或 抬頭顯示 是一組在遊戲過程中始終可見或可訪問的 UI 元素,例如得分顯示、健康計量器和菜單按鈕。對於大多數遊戲來說,包含 HUD 是至關重要的,因為它顯示了幫助玩家成功完成遊戲目標的信息。
一個常見的 HUD 元素是健康計量器,左側有一個圖標,可以改編為計時條、進度條或類似的東西。

使用 危險太空站 作為起點,並以 UI 基礎知識 - HUD 計量器 作為完成的參考,這個教程演示了:
- 設置和使用 設備模擬器 在多個模擬屏幕上測試您的設計。
- 使用 StarterGui 作為設計和存儲容器。
- 如何在內置 Roblox 控件和設備缺口/島嶼周圍定位/調整 UI 元素,例如現代手機上的相機缺口。
- 如何用自己的計量器替換默認的 Roblox 健康計量器,並將其連接到角色的健康水平。
- 如何為健康計量器的中心部分添加動畫,並在五個顏色漸變關鍵點(紅色、橙色、黃色、青檸、綠色)之間設置其顏色。
啟用設備模擬器
Roblox 本質上是 跨平台 的,因為玩家可以在手機或平板電腦上發現並加入遊戲,然後在 PC 或主機上繼續他們的進度。移動設備(手機和平板電腦)擁有最少的屏幕空間,因此您的 UI 元素必須適合較小的屏幕,並且對玩家清晰可見。
測試跨平台的 UI 設計的最佳方法是 Studio 的 設備模擬器。此工具提供了一組預設設備選擇,並允許您添加自己的自定義預設。
在 Studio 中打開 危險太空站 模板。
在 Studio 的 測試 菜單中,切換開啟 設備模擬器。
在主視口上方的工具欄中,選擇一個手機模擬,例如 iPhone X 或 Samsung Galaxy A51。然後,將視圖大小設置為 適合窗口 以利用 Studio 中的最大空間。

創建屏幕容器
ScreenGui 容器持有 UI 對象(GuiObjects)以顯示在玩家的屏幕上(在本教程中,整個健康計量器)。要將 ScreenGui 及其子對象顯示給每個加入遊戲的玩家,請將其放置在 StarterGui 容器內。當玩家加入並且他們的角色首次生成時,ScreenGui 及其內容會克隆到該玩家的 PlayerGui 容器中,該容器位於 Players 容器內。

要插入一個空的 ScreenGui:
在 資源管理器 窗口中,找到 StarterGui 容器。

將鼠標懸停在容器上,單擊 ⊕ 按鈕,並插入一個 ScreenGui。

將新容器重命名為 HUDContainer 以反映其用途。

利用安全區域
現代手機充分利用整個屏幕,但通常包括缺口、切口和其他佔用屏幕空間的元素。每個 Roblox 遊戲還包括 頂部欄控件,以便快速訪問主菜單、聊天、排行榜 等。

為了確保玩家可以看到並訪問所有 UI 而不受阻礙,Roblox 提供了 ScreenInsets 屬性,該屬性控制 ScreenGui 內容的 安全區域 插入。您在 ScreenGui 中定位的每個 UI 對象都是相對於插入邊界的。

雖然 CoreUISafeInsets 的默認設置確保所有 UI 對象遠離 Roblox UI 和設備切口,但 DeviceSafeInsets 可能是利用有限屏幕空間的更好選擇,如下所示。

在 資源管理器 窗口中,選擇 HUDContainer。

在 屬性 窗口中,將 ScreenInsets 屬性設置為 DeviceSafeInsets。

設置邊緣填充
將 ScreenInsets 設置為 DeviceSafeInsets 後,內容現在可以直接延伸到屏幕的物理頂邊。然而,少量的 填充 可以幫助將健康計量器(以及容器內的其他對象)稍微推離屏幕邊緣,以獲得更乾淨的外觀並防止它們被裁剪。

應用填充到 UI 容器的一種方法是插入 UIPadding 修飾符:
在 HUDContainer 中插入一個 UIPadding 修飾符。

選擇新的 UIPadding 對象,為容器的所有邊緣輸入值 0, 16(PaddingBottom、PaddingLeft、PaddingRight、PaddingTop)。這會在容器周圍應用 16 像素的填充,無論屏幕的解析度如何。

構建健康計量器
在 屏幕容器配置 完成後,您可以開始使用 Roblox UI 對象(例如 框架 和 圖像標籤)構建健康計量器。

創建父框架
類似於 Figma 和 Photoshop 等設計應用程序,Roblox 中的 Frame 作為其他 UI 對象的容器。在本教程中,整個健康計量器將包含在一個父框架中,使其在各種 HUD 布局中重新定位變得簡單。
將新框架實例重命名為 MeterBar。

定位框架
在 Roblox 中,UI 對象的位置由包含 UDim2 坐標集表示,該坐標集包含 X 和 Y 軸的 Scale 和 Offset 值:


要將 UI 對象定位在屏幕容器的右上角,Scale 是最佳方法,因為 X 值為 1(100%)表示容器的右邊緣,無論屏幕的物理像素大小如何。同樣,Y 的比例值為 0(0%)表示容器的頂邊。

此外,您需要為父框架設置右上角的 錨點 以定義其原點。可接受的值在 0 和 1 之間,相對於對象的大小,因此錨點值 1, 0 將框架的錨點放在其右上角。

在 資源管理器 窗口中,選擇您之前插入的 MeterBar 框架。

為 AnchorPoint 屬性輸入 1, 0。框架現在應該位於 設備安全區域 的右上角,因為 填充 的結果稍微向內縮。

調整框架大小
與位置類似,UI 對象的 Size 由包含 X 和 Y 軸的 UDim2 坐標集表示,該坐標集包含 Scale 和 Offset 值。
默認情況下,新框架的大小為 {0, 100},{0, 100},這意味著寬度(X)和高度(Y)均為 100 像素。雖然嚴格的像素值在某些情況下是有用的,但許多 UI 元素在多個屏幕上設置為整體屏幕容器大小的 百分比 時會更具響應性。
選擇 MeterBar 框架,訪問 屬性 窗口並導航到 Size 屬性。
輸入值 0.35, 0, 0.05, 0 以設置 35% 寬和 5% 高的百分比大小,且不添加像素偏移。

美化框架
默認情況下,Frames 填充為純白色。最終的健康計量器應具有較深且稍微不透明的填充,以及深色邊框,以便在淺色和深色背景上更突出。

選擇 MeterBar 框架,為 BackgroundColor3 屬性輸入 0。Studio 將自動將其轉換為 RGB 值 [0, 0, 0]。
為 BackgroundTransparency 屬性輸入 0.75。在 Roblox 中,透明度範圍從 0(完全不透明)到 1(完全透明),因此 0.75 等於在其他應用程序(例如 Figma 或 Photoshop)中的 25% 不透明度。

為了最終確定計量器框架的樣式,您可以將角落圓化以形成 "藥丸" 形狀,而不是尖銳的矩形。
在 MeterBar 框架中插入一個 UICorner 實例。

選擇新的 UICorner,將 CornerRadius 設置為 0.5, 0。使用 比例 值 0.5(50%)而不是像素值對於計量器條特別方便,因為它確保無論容器變得多高或多寬,都會形成完全圓形的曲線。

創建內部填充
現在健康計量器的容器框架已完成,您可以添加一個 內部填充 部分來表示角色的可變健康。由於它只需要是一個實心填充區域,因此在父框架內部的子 Frame 是合適的。

在 MeterBar 框架中插入一個子 Frame。
將新框架實例重命名為 InnerFill。

選擇 InnerFill,設置以下屬性:
- AnchorPoint = 0, 0.5(左邊緣和垂直中心)
- Position = 0, 0, 0.5, 0
- Size = 1, 0, 1, 0
由於框架的子對象相對於其父對象定位和調整大小,因此使用比例使內部框架填滿父框架的全部寬度和高度,從父框架的左邊緣開始。

為了匹配父框架的 "藥丸" 形狀,在 InnerFill 中插入一個額外的 UICorner。

選擇新的 UICorner 修飾符,將其 CornerRadius 屬性設置為 0.5, 0 以匹配父 MeterBar 框架的 "藥丸" 形狀。

為了更好地表示滿計量器表示良好健康,選擇 InnerFill 並將其 BackgroundColor3 屬性設置為 [0, 225, 50](在後面的任務中,您將 編寫腳本 使此顏色根據實際健康變化)。

添加圖標
為了更清楚地指示計量器的用途,您可以在左側添加一個 圖像標籤,在這種情況下是一個紅色心形圖標,通常象徵健康或生命。

在 MeterBar 框架中插入一個 ImageLabel。此對象允許您應用已作為貼圖上傳到 Roblox 的 2D 圖像資產。
將新標籤實例重命名為 Icon。

選擇 Icon,將其 ZIndex 屬性設置為 2。雖然新插入的 UI 對象總是層疊在之前插入的對象前面,但此更改確保圖標始終顯示在計量器框架元素的前面。

為了確保圖標 ImageLabel 始終保持 1:1 的長寬比,插入一個 UIAspectRatioConstraint。雖然此 約束 具有可自定義的屬性來控制長寬比,但您可以保持其默認值不變。

選擇 Icon,通過更改以下屬性來最終確定外觀和位置:
- AnchorPoint = 0.5, 0.5(中心錨點)
- BackgroundTransparency = 1(100% 透明)
- Position = 0, 0, 0.5, 0(計量器的左側和垂直中心)

限制大小
雖然 比例高度 為 0.05(5%)在現代手機屏幕和 16:9 或更寬的遊戲顯示器上看起來不錯,但在平板電腦屏幕和舊手機上,計量器可能看起來稍微太高。您可以通過從 設備模擬器 模擬一個平板電腦(例如 iPad 第七代)來檢查這一點。


為了使計量器條的高度在更寬的屏幕上保持更一致,您可以應用 UISizeConstraint 來限制最大像素高度。
在 MeterBar 框架中插入一個 UISizeConstraint。

選擇新的約束,將其 MaxSize 屬性設置為 inf, 20,以將其高度限制為 20 像素,同時不強制限制寬度。

現在,計量器條在更寬和更高的屏幕之間保持更一致的高度。

替換默認健康計量器
Roblox 遊戲包括一個默認健康計量器,當角色受到傷害時會顯示。如果您保持默認計量器可見,它將重複並可能與自定義計量器重疊。

禁用默認計量器
要禁用默認健康計量器,您將在 StarterPlayerScripts 中使用一個 客戶端腳本(LocalScript),該腳本調用 StarterGui:SetCoreGuiEnabled()。
在 資源管理器 窗口中,展開 StarterPlayer 容器並找到其中的 StarterPlayerScripts 容器。

在容器中插入一個新的 LocalScript,並將其重命名為 HideDefaultHealthMeter 以描述其用途。StarterPlayerScripts 中的腳本在本地玩家加入遊戲時自動運行,使其成為運行永久隱藏默認計量器的腳本的理想容器。

當您插入新腳本時,它會自動在新的腳本編輯器選項卡中打開(如果沒有,請雙擊 資源管理器 窗口中的腳本)。
將以下代碼粘貼到 HideDefaultHealthMeter 腳本中:
HideDefaultHealthMeterlocal StarterGui = game:GetService("StarterGui")-- 隱藏默認健康計量器StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Health, false)代碼解釋行 目的 1 獲取對核心 服務 的引用,StarterGui,它表示您創建自定義健康計量器的同一容器,其內容克隆到每個加入遊戲的玩家的 PlayerGui 容器中。 4 調用服務的 SetCoreGuiEnabled() 方法,並指示禁用默認健康計量器(false)。
如果您現在進行遊戲測試並受到傷害,您會注意到默認計量器被禁用並隱藏(您將在下一部分中編寫腳本使自定義計量器 反映健康變化)。

監聽健康變化
所有默認的 Roblox 角色模型都包含一個 Humanoid 類,該類為角色提供特殊行為和功能,例如設置其行走/奔跑速度和管理其健康。Health 在服務器上 複製 到每個玩家的客戶端,您可以檢測這些變化以更新自定義健康計量器的大小和顏色。
在 資源管理器 窗口中,找到 StarterCharacterScripts 容器,該容器位於 StarterPlayer 中。

在容器中插入一個新的 LocalScript,並將其重命名為 UpdateCustomMeter 以描述其用途。StarterCharacterScripts 中的腳本在玩家的角色每次生成時自動運行,使其成為運行每次重生時完全重置健康計量器的腳本的理想容器。

在 UpdateCustomMeter 腳本的編輯器窗口中,粘貼以下代碼:
UpdateCustomMeterlocal Players = game:GetService("Players")-- 本地玩家、角色和人形的引用local player = Players.LocalPlayerlocal character = player.Characterlocal humanoid = character:WaitForChild("Humanoid")-- 參考計量器條內部框架local playerGui = player:WaitForChild("PlayerGui")local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill-- 漸變序列顏色(紅色、橙色、黃色、青檸、綠色)local gradient = {Color3.fromRGB(225, 50, 0),Color3.fromRGB(255, 100, 0),Color3.fromRGB(255, 200, 0),Color3.fromRGB(150, 225, 0),Color3.fromRGB(0, 225, 50)}-- 根據分數點獲取漸變序列中的顏色的函數local function getColorFromSequence(fraction: number): Color3-- 漸變中的每種顏色定義了一個部分的開始和/或結束local numSections = #gradient - 1-- 每個部分表示 1 的一部分local sectionSize = 1 / numSections-- 確定請求的分數落入哪個部分local sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize-- 獲取部分的開始和結束顏色local sectionColorStart = gradient[sectionStartIndex]local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart-- 將分數標準化為 0 到 1 之間的數字local fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize-- 根據標準化的分數在開始和結束之間插值return sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)endlocal function onHealthChanged()-- 計算新健康作為最大值的百分比local healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)-- 將計量器條設置為新的大小/顏色目標meterBarInner.Size = UDim2.new(healthFraction, 0, 1, 0)meterBarInner.BackgroundColor3 = getColorFromSequence(healthFraction)end-- 監聽人形健康的變化humanoid.HealthChanged:Connect(onHealthChanged)-- 最初設置(或重置)計量器條的大小/顏色為當前健康onHealthChanged()代碼解釋行 目的 4‑6 獲取對本地 Player、其 Character 模型和其中的 Humanoid 類的引用。 9‑10 獲取對計量器的 InnerFill 對象的引用,該對象必須在健康變化時調整大小和重新上色。 13‑19 聲明五種顏色的數組(紅色、橙色、黃色、青檸、綠色),以在各個點重新上色計量器;例如,100% 健康為綠色,50% 為黃色,0% 為紅色,或在關鍵點之間的任何分數的混合。 22‑41 輔助函數,返回漸變顏色關鍵點之間的顏色混合。 43‑50 處理健康變化的函數。在這裡,它計算新健康作為角色的 MaxHealth 的百分比,將 InnerFill 的大小設置為該比例百分比,並將其重新上色為從 getColorFromSequence() 函數返回的顏色。 53 主要 事件 連接,檢測從服務器複製的 Health 變化並調用 onHealthChanged() 函數。 56 最初(在角色生成或重生時)調用 onHealthChanged() 函數,以將 InnerFill 的大小和顏色設置為正確的百分比。通常這將是完整的寬度和綠色。
如果您現在進行遊戲測試,您會注意到自定義計量器在角色受到傷害時正確更新大小和顏色:
動畫計量器條
為了為自定義計量器添加額外的光澤,您可以通過 補間 動畫健康變化,逐漸改變計量器條的大小和顏色,持續 ½ 秒。
訪問您之前編輯的 UpdateCustomMeter 腳本的腳本編輯器選項卡。
選擇所有行(CtrlA 或 ⌘A),然後用以下代碼粘貼覆蓋它們(CtrlV 或 ⌘V):
UpdateCustomMeterlocal Players = game:GetService("Players")local TweenService = game:GetService("TweenService")-- 本地玩家、角色和人形的引用local player = Players.LocalPlayerlocal character = player.Characterlocal humanoid = character:WaitForChild("Humanoid")-- 補間屬性local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)-- 參考計量器條內部框架local playerGui = player:WaitForChild("PlayerGui")local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill-- 漸變序列顏色(紅色、橙色、黃色、青檸、綠色)local gradient = {Color3.fromRGB(225, 50, 0),Color3.fromRGB(255, 100, 0),Color3.fromRGB(255, 200, 0),Color3.fromRGB(150, 225, 0),Color3.fromRGB(0, 225, 50)}-- 根據分數點獲取漸變序列中的顏色的函數local function getColorFromSequence(fraction: number): Color3-- 漸變中的每種顏色定義了一個部分的開始和/或結束local numSections = #gradient - 1-- 每個部分表示 1 的一部分local sectionSize = 1 / numSections-- 確定請求的分數落入哪個部分local sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize-- 獲取部分的開始和結束顏色local sectionColorStart = gradient[sectionStartIndex]local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart-- 將分數標準化為 0 到 1 之間的數字local fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize-- 根據標準化的分數在開始和結束之間插值return sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)endlocal function onHealthChanged()-- 計算新健康作為最大值的百分比local healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)-- 將計量器條補間到新的大小/顏色目標local tweenGoal = {Size = UDim2.new(healthFraction, 0, 1, 0),BackgroundColor3 = getColorFromSequence(healthFraction)}local meterBarTween = TweenService:Create(meterBarInner, tweenInfo, tweenGoal)meterBarTween:Play()end-- 監聽人形健康的變化humanoid.HealthChanged:Connect(onHealthChanged)-- 最初設置(或重置)計量器條的大小/顏色為當前健康onHealthChanged()關鍵新增/更改行 目的 2 獲取對 TweenService 的引用,以在腳本中實現補間功能。 10 創建一個 TweenInfo 構造函數,定義預期補間的持續時間、緩動樣式 和 緩動方向。 52‑57 而不是像 之前的版本 一樣簡單地設置計量器的大小和顏色,聲明一個 tweenGoal 表,包含目標大小/顏色,使用 tweenInfo 和 tweenGoal 參數創建一個新的補間,並播放新的補間。
如果您現在進行遊戲測試,您會注意到自定義計量器在每次健康變化時進行補間:
添加傷害效果
默認健康計量器系統在角色受到傷害時會在屏幕邊緣顯示短暫、微妙的紅色色調。通過 禁用默認計量器,此效果被移除,但您可以用自己的實現替換它。
訪問您之前編輯的 UpdateCustomMeter 腳本的腳本編輯器選項卡。
選擇所有行並用以下代碼粘貼覆蓋它們:
UpdateCustomMeterlocal Workspace = game:GetService("Workspace")local Players = game:GetService("Players")local TweenService = game:GetService("TweenService")-- 本地玩家、角色和人形的引用local player = Players.LocalPlayerlocal character = player.Characterlocal humanoid = character:WaitForChild("Humanoid")-- 補間屬性local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)-- 用於存儲/緩存角色健康的變量local cachedHealth = humanoid.Health / humanoid.MaxHealth-- 獲取(或創建新)顏色校正效果在玩家相機內local colorCorrection = Workspace.CurrentCamera:FindFirstChildWhichIsA("ColorCorrectionEffect") or Instance.new("ColorCorrectionEffect", Workspace.CurrentCamera)colorCorrection.Name = "DamageColorEffect"-- 參考計量器條內部框架local playerGui = player:WaitForChild("PlayerGui")local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill-- 漸變序列顏色(紅色、橙色、黃色、青檸、綠色)local gradient = {Color3.fromRGB(225, 50, 0),Color3.fromRGB(255, 100, 0),Color3.fromRGB(255, 200, 0),Color3.fromRGB(150, 225, 0),Color3.fromRGB(0, 225, 50)}-- 根據分數點獲取漸變序列中的顏色的函數local function getColorFromSequence(fraction: number): Color3-- 漸變中的每種顏色定義了一個部分的開始和/或結束local numSections = #gradient - 1-- 每個部分表示 1 的一部分local sectionSize = 1 / numSections-- 確定請求的分數落入哪個部分local sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize-- 獲取部分的開始和結束顏色local sectionColorStart = gradient[sectionStartIndex]local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart-- 將分數標準化為 0 到 1 之間的數字local fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize-- 根據標準化的分數在開始和結束之間插值return sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)endlocal function onHealthChanged()-- 計算新健康作為最大值的百分比local healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)-- 將計量器條補間到新的大小/顏色目標local tweenGoal = {Size = UDim2.new(healthFraction, 0, 1, 0),BackgroundColor3 = getColorFromSequence(healthFraction)}local meterBarTween = TweenService:Create(meterBarInner, tweenInfo, tweenGoal)meterBarTween:Play()-- 如果新健康低於緩存的健康,顯示傷害效果if healthFraction < cachedHealth then-- 緩存新健康值cachedHealth = healthFraction-- 將顏色校正設置為紅色作為初始色調,然後進行補間colorCorrection.TintColor = Color3.fromRGB(255, 25, 25)colorCorrection.Saturation = 2.5-- 將色調補間回白色(中性,無色調變化)local colorCorrectionTweenGoal = {TintColor = Color3.fromRGB(255, 255, 255),Saturation = 0}local colorCorrectionTween = TweenService:Create(colorCorrection, tweenInfo, colorCorrectionTweenGoal)colorCorrectionTween:Play()endend-- 監聽人形健康的變化humanoid.HealthChanged:Connect(onHealthChanged)-- 最初設置(或重置)計量器條的大小/顏色為當前健康onHealthChanged()關鍵新增/更改行 目的 14 設置一個佔位符引用(cachedHealth)以跟踪角色的健康量,以便您可以比較變化是否較低(傷害)。 17‑18 在初始角色生成時,在玩家當前的 Camera 中創建一個新的 ColorCorrectionEffect,或在後續重生時獲取對同一實例的引用。通過將此 後處理效果 置於玩家的相機中,它僅適用於他們的本地屏幕,而不適用於服務器上的每個玩家屏幕。 68‑83 首先執行條件檢查以確認健康變化低於 cachedHealth 值,表示受到傷害;如果是,則將 cachedHealth 設置為新值。接下來,將 ColorCorrectionEffect 的色調設置為 [255, 25, 25](紅色)並提高飽和度,然後將色調補間回默認的中性白色([255, 255, 255])並將飽和度設置為 0。
如果您現在進行遊戲測試,您會注意到每當角色受到傷害時,屏幕會短暫閃爍紅色:



