立即開始
中級教學

創建互動式 UI

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

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

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

使用 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 進入其父容器中的橫向行或縱向列的一種強大方式,包括應用 彈性佈局 的能力。

    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 中的 InnerFill 框架。
    屬性窗口顯示 InnerFill 框架的預期值。
    BackgroundVolumeSlider 附帶已修改的 InnerFill 顏色。

創建關閉按鈕

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

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

    Explorer 窗口顯示新插入的 ImageButton 並將其重命名為 CloseButton。 設置菜單的上方左側一個空的 ImageButton。
  2. 選擇 CloseButton,並設置以下屬性:

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

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

創建控制模塊

可擴展的 控制模塊 設置使互動式 UI 管理比在每個對象中放置單獨腳本更簡化。ModuleScripts 通過允許您在客戶端服務器邊界的不同側或相同側的腳本之間重用代碼來促進這一可擴展功能。

有狀態對象控制器

以下有狀態對象控制器模塊讓您將行為附加到 UI 對象,例如 SettingsButtonSettingsMenu,並輕鬆切換/淡入淡出各種狀態。要創建該模組:

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

    Explorer 窗口顯示 ReplicatedStorage 容器內的 StatefulObjectController 模組。
  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 行取消任何運行中的 tweens 以防止衝突,而第 49 行執行該狀態的 tween。

滑塊控制器

另一個模組初始化並控制這兩個音量滑塊。它還允許您將回調函數連接到每個滑塊,以便檢測玩家對滑塊的互動並在體驗中應用所需的變化。

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

    Explorer 窗口顯示 ReplicatedStorage 容器內的 SliderController 模組。
  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)
    -- 設定初始值
    self:setValue(self.value)
    -- 連接檢測器到玩家操作
    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
    -- 更新手柄位置和內部框架大小以匹配
    self.handle.Position = UDim2.fromScale(clampedValue, 0.5)
    self.innerFill.Size = UDim2.fromScale(clampedValue, 1)
    -- 在最新值上運行用戶回調
    local changeSuccess, changeResult = pcall(self.onChanged, clampedValue)
    if not changeSuccess then
    warn("滑塊回調中的錯誤:", 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 窗口顯示 HUDContainer 中的 SettingsScript 腳本。
  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
    -- 初始化設置按鈕
    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"
    })
    -- 初始化設置菜單框架
    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"
    })
    -- 初始化效果音量滑塊
    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,
    })
    -- 初始化背景音量滑塊
    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,
    })
    -- 將按鈕連接到玩家操作
    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() 函數進行初始化,並將 SettingsButton 按鈕作為初始化的對象。
    1225傳遞了一個 states 表,該表具有兩個唯一狀態 menuOpenmenuClosed。每個狀態包含一個過渡來聲明(通過 TweenInfo)特定狀態將如何達到 properties 表中定義的目標屬性。在這種情況下,menuOpen 聲明將按鈕的 Rotation 狀態變更為 45°,並應用 0.5 秒的 Exponential 畫面過渡,而 menuClosed 有效地將按鈕恢復為其默認的 0 旋轉狀態。
    26按鈕的 初始 狀態設置為 menuClosed(這可以設置為任何名稱表中的狀態)。

    腳本稍後的部分(行數 76-86)中,按鈕連接到玩家互動以觸發 UI 狀態變更:

    行數目的
    7682SettingsButton 連接到 Activated 事件以調用匿名函數。在匿名函數內,第 7779 行在 menuOpenmenuClosed 之間切換 targetState 變數。第 80 行然後調用 setState() 將按鈕的狀態設置為 targetState,第 81 行對 SettingsMenu 執行相同操作,以便它在去激活 SettingsButton 時切換開啟或關閉。
    8386CloseButton 被激活時,將 SettingsButtonSettingsMenu 的狀態設置為 menuClosed

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

    行數目的
    3031宣告了一個本地引用 settingsMenu,並用 StatefulObjectController.hydrate() 函數進行初始化,並將 SettingsMenu 框架作為初始化的對象。
    3246與設置按鈕類似,傳遞了一個 states 表,該表具有兩個唯一狀態,menuOpenmenuClosed。這裡,menuOpen 聲明框架的 Position 狀態變更為 UDim2.fromScale(0.5, 0.5),並應用 0.5 秒的 Bounce 畫面過渡,此外,將框架的 Visible 狀態設為 true。相比之下,menuClosed 聲明位置狀態變更為 UDim2.fromScale(0.5, 0.4),並將 Visible 設置為 false,但第 41 行的 TweenInfo 定義為 0 的持續時間將使狀態變更瞬間發生。
    48設置框架的初始狀態為 menuClosed

    腳本稍後部分(行數 76-86)連接了設置菜單以響應玩家交互:

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

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

    行數目的
    52將本地引用設置為 EffectsSoundGroup,該組在 SoundService 中。 SoundGroup 允許您相互關聯多個 Sounds,並通過該組的 Volume 屬性控制該組中每個聲音的音量。
    5354宣告了一個本地引用 effectsVolumeSlider,並用 SliderController.hydrate() 函數進行初始化,並將 EffectsVolumeSlider 框架作為初始化的對象。請注意,對於 FindFirstChild() 的第二個參數設置為 true,告知方法在 HUDContainer 分支中向下遞歸搜尋以找到 EffectsVolumeSlider
    55滑塊的初始值設置為當前的 VolumeEffects 聲音組,或作為回退的 0.5
    5660設置回調函數以將滑塊值變更應用於 Effects 聲音組的音量。
    6473與第 5261 行基本相同,除了初始化 BackgroundVolumeSlider 框架於 HUDContainer ⟩ SettingsMenu,並對 Background 聲音組的音量應用滑塊值變更。

    隨著 SettingsScript 的到位,此體驗現在提供了一個完整操作的互動式 UI 示例,將一組相關的 UI 對象鏈接到玩家互動。

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