創建互動式 UI

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

一個 HUD (Heads-Up Display) 在你的遊戲中通常顯示非互動式的 UI 元素,例如在 創建 HUD 儀表 中演示的健康計量器。在此之上,幾乎每個遊戲都需要 互動式 UI,例如響應玩家激活的按鈕、在激活時動畫、與其他互動控制一起進出菜單等。

遊戲內視圖顯示設置按鈕和帶有音量滑塊的設置菜單。

使用 UI 基礎知識 - HUD 儀表 作為起點,並使用 UI 基礎知識 - 互動性 作為完成的參考,這個教程演示了:

  • 如何將設置按鈕放置在屏幕頂部邊緣。
  • 設計包含可互動可拖動滑塊的設置菜單。
  • 使用 ModuleScripts 形成“控制器”模塊,以擴展對具有狀態聲明的 UI 對象的控制。
  • 如何將按鈕連接到玩家激活,以切換設置菜單的顯示與隱藏。
  • 如何連接可拖動的 UI 滑塊,以分別調整音效和背景氛圍的音量。

啟用設備模擬器

創建 HUD 儀表 中所述,手機和平板電腦的屏幕空間最少,因此你的 UI 元素必須適合較小的屏幕,並且對玩家清晰可見。如果你還沒有這樣做,請在 Studio 中啟用 設備模擬器

  1. 在 Studio 中打開 UI 基礎知識 - HUD 儀表 模板。

  2. 從 Studio 的 測試 菜單中,切換開啟 設備模擬器

  3. 從主視口上方的工具欄中,選擇一個手機模擬,例如 iPhone XSamsung Galaxy A51。然後,將視圖大小設置為 適合窗口 以利用 Studio 中的最大空間。

    設備模擬器設置選項顯示在視口窗口的頂部。

創建設置按鈕

GuiButtons 是具有內置功能的互動用戶界面元素,例如多平台的 Activated 事件,當按鈕被點擊或點觸時觸發。GuiButton 類擴展為兩個變體,TextButtonImageButton,本教程使用一個“齒輪”形狀的 ImageButton 來切換設置菜單的開啟或關閉。

用於設置按鈕的 Roblox 組件。

要構建設置按鈕:

  1. Explorer 窗口中,找到 StarterGui 中的 HUDContainer

    Explorer 窗口顯示選中的 HUDContainer。
  2. HUDContainer 中插入一個 ImageButton 並將其重命名為 SettingsButton

    Explorer 窗口顯示新插入的 ImageButton 並重命名為 SettingsButton。 視口中的新 ImageButton。
  3. 選中新的按鈕,在 屬性 窗口中設置以下內容:

    • AnchorPoint = 0.5, 0.25(水平中心和垂直上四分之一)
    • BackgroundTransparency = 1(完全透明)
    • Position = 0.5, 0, 0, 0(頂部中心定位)
    • Size = 0.1, 0, 0.1, 0(一旦約束了長寬比,佔屏幕高度的 10%)
    • Image = rbxassetid://104919049969988(“齒輪”符號的資產 ID)
  4. 在按鈕中插入一個 UIAspectRatioConstraint,並保持默認屬性(1:1 寬高比)。

    Explorer 窗口顯示插入到 SettingsButton 按鈕中的新 UIAspectRatioConstraint。
  5. 為了限制按鈕的最大像素高度,插入一個 UISizeConstraint,並將其 MaxSize 設置為 inf, 44

    Explorer 窗口顯示插入到 SettingsButton 按鈕中的新 UISizeConstraint。
    屬性窗口顯示新 UISizeConstraint 的預期值。
    最終設置按鈕位於屏幕的頂部中心。

創建設置菜單

新的 設置按鈕 將被編寫腳本以切換設置菜單的開啟和關閉,讓玩家隨時訪問設置或其他信息。在本教程中,菜單將包含可互動的滑塊,以獨立調整背景音頻和音效的音量級別。

用於設置菜單的基本組件。

創建父框架

創建 HUD 儀表 中所述,Frame 作為其他 UI 對象的容器。整個設置菜單將使用一個父框架構建,使其作為一個狀態對象進行簡單管理,根據當前狀態對輸入做出不同反應。

  1. HUDContainer 中插入一個 Frame 並將其重命名為 SettingsMenu

    Explorer 窗口顯示新插入的框架並重命名為 SettingsMenu。
  2. 選中 SettingsMenu,設置以下屬性:

    框架重新定位、調整大小並使用透明的海軍藍背景進行樣式設置。
  3. SettingsMenu 中插入一個 UIAspectRatioConstraint,並將其 AspectRatio 屬性設置為 2.5。(2.5:1 寬高比)。

    Explorer 窗口顯示插入到 SettingsMenu 框架中的新 UISizeConstraint。
    屬性窗口顯示新 UISizeConstraint 的預期值。
  4. SettingsMenu 中插入一個 UICorner 修飾符,並將其 CornerRadius 設置為 0.1, 0

    Explorer 窗口顯示插入到 SettingsMenu 框架中的新 UICorner。
    屬性窗口顯示新 UICorner 修飾符的預期值。
  5. 為了約束 SettingsMenu 的像素寬度和高度,插入一個 UISizeConstraint。將其 MaxSize 設置為 800, inf,並將其 MinSize 設置為 350, 0

    Explorer 窗口顯示插入到 SettingsMenu 框架中的新 UISizeConstraint。
    屬性窗口顯示新 UISizeConstraint 的預期值。
    框架樣式設置為圓角。

構建滑塊

為了讓玩家調整音量級別,設置菜單將包含兩個可拖動的 滑塊小部件,由 UIDragDetector 提供支持,這是一個方便的對象,可以促進與 2D 用戶界面元素的互動。


要為第一個滑塊創建一個父容器:

  1. SettingsMenu 容器中插入一個新的 Frame 並將其重命名為 EffectsVolumeSlider

    Explorer 窗口顯示插入到 SettingsMenu 框架中的新框架,重命名為 EffectsVolumeSlider。
  2. 選中 EffectsVolumeSlider 框架,設置以下屬性:

  3. EffectsVolumeSlider 中插入一個新的 UIListLayout。這個佈局修飾符是一種強大的方式,可以自動排列兄弟 GuiObjects 在其父容器中,無論是水平行還是垂直列,包括應用 flex 概念的能力。

    Explorer 窗口顯示插入到 EffectsVolumeSlider 框架中的新 UIListLayout。
  4. 為新的 UIListLayout 設置以下屬性:

滑塊圖標

一個簡單的圖標,包括音頻音符和“爆炸”符號,幫助玩家識別滑塊的用途,當他們打開設置菜單時。

指示設置菜單中滑塊用途的圖標。
  1. EffectsVolumeSlider 框架中插入一個 ImageLabel 並將其重命名為 Icon。這個圖標將幫助玩家理解滑塊控制的遊戲方面。

    Explorer 窗口顯示插入到 EffectsVolumeSlider 框架中的 ImageLabel。
  2. 選中 Icon,設置以下屬性:

    • BackgroundTransparency = 1(完全透明)
    • Size = 2.5, 0, 2.5, 0(一旦約束了長寬比,佔父框架的 250% 高度)
    • Image = rbxassetid://90019827067389(音頻音符和“爆炸”符號的資產 ID)
  3. Icon 中插入一個 UIAspectRatioConstraint,並保持其屬性為默認值(1:1 寬高比)。

    Explorer 窗口顯示插入到 ImageLabel 中的 UIAspectRatioConstraint。 設置菜單中最終的圖標。

範圍框架

圖標 的右側,滑塊的互動部分應包含在另一個 Frame 中。

滑塊互動部分的目標大小和位置。
  1. EffectsVolumeSlider 框架中插入一個新的 Frame 並將其重命名為 SliderFrame。請注意,它必須是 UIListLayout 佈局修飾符的直接 兄弟

    Explorer 窗口顯示插入到 EffectsVolumeSlider 框架中的子框架。
  2. 選中 SliderFrame,設置以下屬性:

  3. SliderFrame 中插入以下修飾符:

    滑塊框架位於圖標的右側。

互動手柄

隨著 滑塊容器 的構建,現在可以為玩家創建一個 可拖動的手柄,以便在遊戲中進行互動。

互動滑塊手柄位於範圍框架內。
  1. SliderFrame 容器中插入一個新的 Frame 並將其重命名為 Handle

    Explorer 窗口顯示插入到 SliderFrame 框架中的子框架並重命名為 Handle。
  2. 選中 Handle,設置以下屬性:

    • AnchorPoint = 0.5(中心錨點)
    • Position = 0.5, 0, 0.5, 0(父框架的水平和垂直中心)
    • Size = 1.2, 0, 1.2, 0(一旦約束了長寬比,佔父框架的 120% 高度)
    • ZIndex = 3(在其他滑塊元素前面可視層)
  3. Handle 中插入以下修飾符:

  4. Handle 中插入一個 UIDragDetector 對象。這個方便的對象促進並鼓勵與 2D 用戶界面元素的互動。

    Explorer 窗口顯示插入到 Handle 框架中的 UIDragDetector。
  5. 為新的 UIDragDetector 設置以下屬性:

  6. 為了確保手柄的線性拖動範圍限制在其容器內,將其 BoundingUI 屬性鏈接到 SliderFrame 容器:

    1. 選中 UIDragDetector
    2. 點擊其 BoundingUI 屬性在 屬性 窗口中。
    3. 回到 Explorer 窗口,點擊手柄的父項 SliderFrame
    圖示顯示將檢測器的 BoundingUI 屬性鏈接到 SliderFrame 容器的過程。

    現在 BoundingUI 屬性鏈接反映了 SliderFrame 容器:

    屬性窗口顯示檢測器的 BoundingUI 屬性鏈接到 SliderFrame 容器。

如果你現在進行遊戲測試,你將能夠在其父容器內左右拖動手柄:

內部填充

為了更清楚地指示滑塊控制 0% 到 100% 的範圍,你可以在容器的左側添加一個 內部填充,這將與手柄的變量位置同步。

插入到 SliderFrame 中的滑塊內部填充部分。
  1. SliderFrame 容器中插入一個新的 Frame 並將其重命名為 InnerFill

    Explorer 窗口顯示插入到 SliderFrame 框架中的子框架並重命名為 InnerFill。
  2. InnerFill 框架設置以下屬性:

  3. 為了匹配父 SliderFrame 容器的“藥丸”形狀,插入一個 UICorner 修飾符,並將其 CornerRadius 屬性設置為 0.5, 0

    Explorer 窗口顯示插入到 InnerFill 框架中的 UICorner 修飾符。
    屬性窗口顯示新 UICorner 的預期值。
    InnerFill 框架樣式設置為藍色背景和圓角。

複製滑塊

隨著 第一個滑塊 的構建,你可以輕鬆地複製它並修改一些視覺方面,以指示另一個用途,在這種情況下,背景音頻的音量級別由音樂音符的圖標表示。

背景音頻滑塊的目標位置。
  1. 選中完成的 EffectsVolumeSlider 對象。

    Explorer 窗口顯示選中的完成的 EffectsVolumeSlider。
  2. 複製它 (CtrlDD),然後將複製的對象重命名為 BackgroundVolumeSlider

    Explorer 窗口顯示重命名為 BackgroundVolumeSlider 的複製滑塊。
  3. 將複製的 Position 更改為 0.5, 0, 0.7, 0,以將其移動到第一個滑塊的下方。

    BackgroundVolumeSlider 位置在 EffectsVolumeSlider 之下。
  4. 展開 BackgroundVolumeSlider 的頂層分支,選中 Icon 圖像標籤,並將其 Image 屬性更改為 rbxassetid://101125859760167(音樂音符符號的資產 ID)。

    Explorer 窗口顯示 BackgroundVolumeSlider 中的 Icon 標籤。
    屬性窗口顯示 Icon 標籤的預期值。
    BackgroundVolumeSlider 的圖標圖像已修改。
  5. 展開 SliderFrameHandle 分支,選中其中的 UIStroke 修飾符,並將其 Color 屬性設置為 [255, 0, 125](品紅色)。

    Explorer 窗口顯示 BackgroundVolumeSlider 的手柄中的 UIStroke 修飾符。
    屬性窗口顯示 UIStroke 修飾符的預期值。
    BackgroundVolumeSlider 的手柄圖標已修改。
  6. 選中 SliderFrame 中的 InnerFill 框架,並將其 BackgroundColor3 屬性更改為相同的品紅色 ([255, 0, 125])

    Explorer 窗口顯示 BackgroundVolumeSlider 的 SliderFrame 容器中的 InnerFill 框架。
    屬性窗口顯示 InnerFill 框架的預期值。
    BackgroundVolumeSlider 的 InnerFill 顏色已修改。

創建關閉按鈕

設置菜單的最後一個元素是 關閉按鈕,它為玩家提供了另一個輸入來關閉菜單(位於頂部中心的 SettingsButton 將提供相同的功能)。

設置菜單,右上角顯示關閉按鈕。
  1. SettingsMenu 容器中插入一個新的 ImageButton 並將其重命名為 CloseButton

    Explorer 窗口顯示插入到 SettingsMenu 中的新 ImageButton 並重命名為 CloseButton。 空的 ImageButton 位於設置菜單的左上角。
  2. 選中 CloseButton,設置以下屬性:

  3. 在按鈕中插入一個 UIAspectRatioConstraint,並保持默認屬性(1:1 寬高比)。

    Explorer 窗口顯示插入到 CloseButton 按鈕中的 UIAspectRatioConstraint。 最終的關閉按鈕位於設置菜單的右上角。

創建控制模塊

可擴展的 控制模塊 設置使互動式 UI 管理比在每個對象中放置單獨的腳本更為簡化。ModuleScripts 促進了這種可擴展的功能,讓你可以在客戶端-服務器邊界的不同側之間或同一側之間重用代碼。

有狀態對象控制器

以下有狀態對象控制器模塊讓你可以將行為附加到 UI 對象,例如 SettingsButtonSettingsMenu,並輕鬆地在各種狀態之間切換/動畫。要創建該模塊:

  1. ReplicatedStorage 容器中插入一個 ModuleScript 並將其重命名為 StatefulObjectController

    Explorer 窗口顯示 StatefulObjectController 模塊在 ReplicatedStorage 容器內。
  2. 將以下代碼粘貼到模塊中:

    StatefulObjectController
    local TweenService = game:GetService("TweenService")
    local StatefulObjectController = {}
    StatefulObjectController.__index = StatefulObjectController
    export type StateName = string
    export type State = {
    transition: TweenInfo,
    properties: { [string]: any },
    }
    function StatefulObjectController.hydrate(props: {
    object: Instance,
    states: { [StateName]: State },
    initialStateName: StateName
    })
    local object, states, initialStateName = props.object, props.states, props.initialStateName
    local self = setmetatable({
    states = states,
    currentStateName = initialStateName,
    tweens = {},
    }, StatefulObjectController)
    -- Create tweens for reuse to avoid making new tweens every time state is changed
    for stateName, state in states do
    self.tweens[stateName] = TweenService:Create(object, state.transition, state.properties)
    end
    self:setState(self.currentStateName)
    return self
    end
    function StatefulObjectController:setState(stateName: StateName)
    local stateTween: Tween = self.tweens[stateName]
    if not stateTween then
    warn(string.format("Attempted to set %s to unknown state '%s'", self.object:GetFullName(), stateName))
    return
    end
    self.currentStateName = stateName
    -- Make sure other tweens aren't conflicting
    for _, tween in self.tweens do
    tween:Cancel()
    end
    stateTween:Play()
    end
    return StatefulObjectController
    行數目的
    610定義並導出 Luau 類型,以改善使用此模塊時的自動完成功能和代碼檢查。
    1233用於初始化並將行為附加到有狀態 UI 對象的函數,接受 GuiObject 作為 object,一個狀態及其各自的 TweenInfo 數據的表,以及一個初始狀態名稱。在此函數內,行 2628 為每個狀態構建 Tweens,行 30 調用模塊的 setState() 函數以將對象設置為初始狀態。
    3550用於設置/更改有狀態對象狀態的函數。行 42 將對象的 currentStateName 設置為正在設置的狀態,行 4547 取消任何正在運行的動畫以防止衝突,行 49 執行狀態的動畫。

滑塊控制器

另一個模塊初始化並控制兩個音量滑塊。它還允許你將回調函數連接到每個滑塊,以檢測玩家與滑塊的互動並在遊戲中應用所需的更改。

  1. ReplicatedStorage 容器中插入一個 ModuleScript 並將其重命名為 SliderController

    Explorer 窗口顯示 SliderController 模塊在 ReplicatedStorage 容器內。
  2. 將以下代碼粘貼到模塊中:

    SliderController
    local SliderController = {}
    SliderController.__index = SliderController
    export type Value = number
    export type OnChanged = (Value) -> ()
    function SliderController.hydrate(props: {
    object: Instance,
    onChanged: OnChanged,
    initialValue: Value?
    })
    local object, onChanged, initialValue = props.object, props.onChanged, props.initialValue
    local handle = object:FindFirstChild("Handle", true)
    if not handle then
    warn(string.format("Attempted to hydrate slider %s but couldn't find Handle", object:GetFullName()))
    end
    local innerFill = object:FindFirstChild("InnerFill", true)
    if not innerFill then
    warn(string.format("Attempted to hydrate slider %s but couldn't find InnerFill", object:GetFullName()))
    end
    local dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
    if not dragDetector then
    warn(string.format("Attempted to hydrate slider %s but couldn't find UIDragDetector", object:GetFullName()))
    end
    local self = setmetatable({
    handle = handle,
    innerFill = innerFill,
    dragDetector = dragDetector,
    value = initialValue or 0.5,
    onChanged = onChanged,
    }, SliderController)
    -- Set initial value
    self:setValue(self.value)
    -- Connect detector to player manipulation
    self.dragConnection = dragDetector.DragContinue:Connect(function()
    self:setValue(handle.Position.X.Scale)
    end)
    return self
    end
    function SliderController:setValue(value: Value)
    local clampedValue = math.clamp(value, 0, 1)
    self.value = clampedValue
    -- Update the handle position and inner frame size to match
    self.handle.Position = UDim2.fromScale(clampedValue, 0.5)
    self.innerFill.Size = UDim2.fromScale(clampedValue, 1)
    -- Run the user's callback with the latest value
    local changeSuccess, changeResult = pcall(self.onChanged, clampedValue)
    if not changeSuccess then
    warn("Error in slider callback:", changeResult)
    end
    end
    return SliderController
    行數目的
    746用於初始化並將行為附加到滑塊元素的函數,接受滑塊的父 Frame 作為 object,一個 onChanged 回調函數來處理滑塊更改,以及滑塊手柄位置的初始值。在函數內,行 1427 確認滑塊的 手柄內部填充UIDragDetector 元素存在。行 38 調用模塊的 setValue() 函數,行 4143 將拖動檢測器的 DragContinue 事件連接到模塊的 setValue() 函數(見下一行的詳細信息)。
    4861用於設置滑塊值的函數。在函數內,行 5354 確保手柄的位置和內部填充的大小保持同步,行 57 將更改的值傳遞給回調函數,以便你可以根據需要利用該值。

創建設置腳本

隨著 設置按鈕設置菜單 的完成,你可以用一個腳本將所有內容連接在一起,該腳本利用 控制模塊

  1. HUDContainer 中插入一個新的 LocalScript 並將其重命名為 SettingsScript 以描述其目的。請注意,該腳本應與 SettingsMenuSettingsButton 在同一層級(兄弟),這是它將管理的頂層 UI 對象。

    Explorer 窗口顯示 SettingsScript 腳本在 HUDContainer 容器內。
  2. 將以下代碼粘貼到腳本中:

    SettingsScript
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local SoundService = game:GetService("SoundService")
    local SliderController = require(ReplicatedStorage.SliderController)
    local StatefulObjectController = require(ReplicatedStorage.StatefulObjectController)
    local HUDContainer = script.Parent
    -- Initialize settings button
    local settingsButton = StatefulObjectController.hydrate({
    object = HUDContainer:FindFirstChild("SettingsButton"),
    states = {
    menuOpen = {
    transition = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out),
    properties = {
    Rotation = 45,
    },
    },
    menuClosed = {
    transition = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out),
    properties = {
    Rotation = 0,
    },
    },
    },
    initialStateName = "menuClosed"
    })
    -- Initialize settings menu frame
    local settingsMenu = StatefulObjectController.hydrate({
    object = HUDContainer:FindFirstChild("SettingsMenu"),
    states = {
    menuOpen = {
    transition = TweenInfo.new(0.5, Enum.EasingStyle.Bounce, Enum.EasingDirection.Out),
    properties = {
    Position = UDim2.fromScale(0.5, 0.5),
    Visible = true,
    },
    },
    menuClosed = {
    transition = TweenInfo.new(0),
    properties = {
    Position = UDim2.fromScale(0.5, 0.4),
    Visible = false,
    },
    },
    },
    initialStateName = "menuClosed"
    })
    -- Initialize effects volume slider
    local effectsAudio = SoundService:FindFirstChild("Effects")
    local effectsVolumeSlider = SliderController.hydrate({
    object = HUDContainer:FindFirstChild("EffectsVolumeSlider", true),
    initialValue = effectsAudio and effectsAudio.Volume or 0.5,
    onChanged = function(value: SliderController.Value)
    if effectsAudio then
    effectsAudio.Volume = value
    end
    end,
    })
    -- Initialize background volume slider
    local backgroundAudio = SoundService:FindFirstChild("Background")
    local backgroundVolumeSlider = SliderController.hydrate({
    object = HUDContainer:FindFirstChild("BackgroundVolumeSlider", true),
    initialValue = backgroundAudio and backgroundAudio.Volume or 0.5,
    onChanged = function(value: SliderController.Value)
    if backgroundAudio then
    backgroundAudio.Volume = value
    end
    end,
    })
    -- Connect buttons to player interaction
    HUDContainer:FindFirstChild("SettingsButton").Activated:Connect(function()
    local targetState = if settingsButton.currentStateName == "menuClosed"
    then "menuOpen"
    else "menuClosed"
    settingsButton:setState(targetState)
    settingsMenu:setState(targetState)
    end)
    HUDContainer:FindFirstChild("CloseButton", true).Activated:Connect(function()
    settingsButton:setState("menuClosed")
    settingsMenu:setState("menuClosed")
    end)
  3. 參考以下部分以探索該腳本如何利用 控制模塊

    10-27 初始化並附加行為到 設置按鈕,具體如下:

    行數目的
    1011聲明一個本地引用 settingsButton,並使用 StatefulObjectController.hydrate() 函數進行初始化,並將 HUDContainer 中的 SettingsButton 按鈕引用為要初始化的對象。
    1225傳遞一個 states 表,包含兩個唯一狀態,menuOpenmenuClosed。每個狀態都包含一個過渡,通過 TweenInfo 聲明特定狀態將如何達到在 properties 表中定義的目標屬性。在這種情況下,menuOpen 聲明按鈕的 Rotation 的狀態變更為 45°,並使用 Exponential 的半秒動畫,而 menuClosed 實際上將按鈕恢復到其默認旋轉 0
    26按鈕的 初始 狀態設置為 menuClosed(這可以設置為 states 表中的任何狀態名稱)。

    在腳本的下方(行 76-86),按鈕連接到玩家互動以觸發 UI 狀態變更:

    行數目的
    7682SettingsButton 連接到 Activated 事件的 GuiButton 類,以調用匿名函數。在匿名函數內,行 7779menuOpenmenuClosed 之間切換 targetState 變量。行 80 然後調用 setState() 將按鈕的狀態設置為 targetState,行 81SettingsMenu 做同樣的事情,以便它隨著 SettingsButton 的激活而切換開啟或關閉。
    8386CloseButton 連接到 Activated 事件以調用匿名函數,該函數將 SettingsButtonSettingsMenu 的狀態設置為 menuClosed

    30-49 初始化並附加行為到 設置菜單,具體如下:

    行數目的
    3031聲明一個本地引用 settingsMenu,並使用 StatefulObjectController.hydrate() 函數進行初始化,並將 HUDContainer 中的 SettingsMenu 框架引用為要初始化的對象。
    3246與設置按鈕類似,傳遞一個 states 表,包含兩個唯一狀態,menuOpenmenuClosed。在這裡,menuOpen 聲明框架的 Position 的狀態變更為 UDim2.fromScale(0.5, 0.5),並使用 Bounce 的半秒動畫,還有 Visible 狀態為 true。相反,menuClosed 聲明位置狀態變更為 UDim2.fromScale(0.5, 0.4),並將 Visible 設置為 false,但行 41TweenInfo0 持續時間有效地使狀態變更立即發生。
    48框架的初始狀態設置為 menuClosed

    在腳本的下方(行 76-86),設置菜單與玩家互動相連:

    行數目的
    81SettingsMenu 設置相同的 targetState,以便與 SettingsButton 的激活同步。
    85CloseButton 被激活時,將 SettingsMenu 的狀態設置為 menuClosed

    51-73 初始化並附加行為到 EffectsVolumeSliderBackgroundVolumeSlider,具體如下:

    行數目的
    52將本地引用設置為 EffectsSoundGroupSoundService 中。SoundGroup 讓你可以相互關聯多個 Sounds,並通過該組的 Volume 屬性控制組中每個聲音的音量。
    5354聲明一個本地引用 effectsVolumeSlider,並使用 SliderController.hydrate() 函數進行初始化,並將 HUDContainer 中的 EffectsVolumeSlider 框架 ⟩ SettingsMenu 引用為要初始化的對象。請注意,FindFirstChild() 的第二個參數 true 告訴該方法在 HUDContainer 分支中遞歸查找以定位 EffectsVolumeSlider
    55滑塊的初始值設置為當前 Effects 聲音組的 Volume,或 0.5 作為後備。
    5660建立回調函數以將滑塊值更改應用於 Effects 聲音組的音量。
    6473基本上與行 52-61 相同,但用於初始化 HUDContainer 中的 BackgroundVolumeSlider 框架 ⟩ SettingsMenu,並將滑塊值更改應用於 Background 聲音組的音量。

隨著 SettingsScript 的到位,遊戲現在提供了一個完全運行的互動式 UI 示例,將一組相關的 UI 對象與玩家互動鏈接在一起。

©2026 Roblox Corporation、Roblox、Roblox 標誌及 Powering Imagination 是我們在美國及其他國家地區的部分註冊與未註冊商標。