Sebuah HUD (Heads-Up Display) dalam pengalaman Anda biasanya menampilkan elemen UI yang tidak interaktif seperti meteran kesehatan yang diperlihatkan dalam Buat meter HUD. Di atas ini, hampir setiap pengalaman membutuhkan UI interaktif seperti tombol yang merespon aktivasi pemain, menganimasikan saat diaktifkan, tween masuk/keluar menu dengan kontrol interaktif lainnya, dll.

Menggunakan UI Fundamentals - Meter HUD sebagai tempat awal dan UI Fundamentals - Interaktivitas sebagai tempat referensi yang telah selesai, tutorial ini menunjukkan:
- Cara menempatkan tombol pengaturan di sepanjang tepi atas layar.
- Desain menu pengaturan yang berisi penggeser interaktif yang dapat diseret.
- Penggunaan ModuleScripts untuk membentuk modul "pengendali" untuk kontrol yang dapat diperluas dari objek UI dengan deklarasi status.
- Cara menghubungkan tombol ke aktivasi pemain untuk mengubah menu pengaturan menjadi terbuka atau tertutup.
- Cara menghubungkan penggeser UI yang dapat diseret untuk menyesuaikan volume efek suara dan ambience latar belakang secara terpisah.
Aktifkan Emulator Perangkat
Seperti yang dicatat dalam Buat meter HUD, ponsel dan tablet memiliki jumlah ruang layar yang paling sedikit, sehingga penting agar elemen UI Anda muat di layar yang lebih kecil dan jelas terlihat oleh pemain. Jika Anda belum melakukannya, aktifkan Emulator Perangkat di Studio:
Buka template UI Fundamentals - Meter HUD di Studio.
Dari menu Test di Studio, aktifkan Emulator Perangkat.
Dari bilah tepat di atas tampilan utama, pilih emulasi ponsel seperti iPhone X atau Samsung Galaxy A51. Kemudian, setel ukuran tampilan ke Sesuaikan dengan Jendela untuk memanfaatkan ruang maksimum di Studio.

Buat tombol pengaturan
GuiButtons adalah elemen antarmuka pengguna interaktif dengan fungsionalitas bawaan seperti peristiwa multi-platform Activated yang dipicu saat tombol diklik atau diketuk. Kelas GuiButton terbagi menjadi dua variasi, TextButton dan ImageButton, dan tutorial ini menggunakan ImageButton berbentuk "gear" untuk mengubah menu pengaturan terbuka atau tertutup.

Untuk membangun tombol pengaturan:
Di jendela Explorer, temukan HUDContainer di dalam StarterGui.

Dengan tombol baru terpilih, tetapkan yang berikut di jendela Properties:
- AnchorPoint = 0.5, 0.25 (tengah horizontal dan kuartal atas vertikal)
- BackgroundTransparency = 1 (sepenuhnya transparan)
- Position = 0.5, 0, 0, 0 (penempatan di tengah atas)
- Size = 0.1, 0, 0.1, 0 (10% dari tinggi layar setelah rasio aspek dibatasi)
- Image = rbxassetid://104919049969988 (ID aset simbol "gear")
Masukkan UIAspectRatioConstraint ke dalam tombol dengan properti default (rasio 1:1 lebar terhadap tinggi).

Untuk membatasi tinggi piksel maksimum tombol, masukkan UISizeConstraint dan set fitur MaxSize ke inf, 44.



Buat menu pengaturan
Tombol pengaturan baru akan diprogram untuk mengubah menu pengaturan terbuka dan tertutup, memberikan pemain akses sesuai permintaan ke pengaturan atau informasi lainnya. Dalam tutorial ini, menu ini akan berisi penggeser interaktif untuk menyesuaikan level volume audio latar belakang dan efek suara secara independen.

Buat frame induk
Seperti yang dicatat dalam Buat meter HUD, Frame berfungsi sebagai wadah untuk objek UI lainnya. Seluruh menu pengaturan akan dibangun dengan satu frame induk, sehingga mudah untuk dikelola sebagai objek yang memiliki status yang bereaksi berbeda tergantung pada keadaan saat ini.
Masukkan Frame ke dalam HUDContainer dan ganti namanya menjadi SettingsMenu.

Dengan SettingsMenu terpilih, tetapkan properti berikut:
- AnchorPoint = 0.5 (tengah anchor)
- BackgroundColor3 = 30, 30, 60 (biru navy)
- BackgroundTransparency = 0.25 (75% opak)
- Position = 0.5, 0, 0.5, 0 (tengah layar)
- Size = 0.75, 0, 0.75, 0 (75% lebar/tinggi dari area layar yang terkurung)

Masukkan UIAspectRatioConstraint ke dalam SettingsMenu dan atur properti AspectRatio menjadi 2.5. (2.5:1 lebar terhadap tinggi).


Masukkan pengubah UICorner ke dalam SettingsMenu dan atur properti CornerRadius ke 0.1, 0.


Untuk membatasi lebar dan tinggi piksel dari SettingsMenu, masukkan UISizeConstraint. Atur MaxSize ke 800, inf dan MinSize ke 350, 0.



Bangun penggeser
Untuk memungkinkan pemain menyesuaikan level volume, menu pengaturan akan berisi dua widget penggeser yang dapat diseret yang ditenagai oleh UIDragDetector, objek yang memudahkan interaksi dengan elemen antarmuka pengguna 2D.
Untuk membuat wadah induk bagi penggeser pertama:
Masukkan Frame baru ke dalam wadah SettingsMenu dan ganti namanya menjadi EffectsVolumeSlider.

Dengan frame EffectsVolumeSlider terpilih, atur sifat berikut:
AnchorPoint = 0.5 (tengah anchor)
BackgroundTransparency = 1 (sepenuhnya transparan)
Position = 0.5, 0, 0.35, 0 (tengah horizontal dan 35% dari atas wadah)
Size = 0.8, 0, 0.1, 0 (80% dari lebar wadah dan 10% dari tingginya)

Masukkan UIListLayout baru ke dalam EffectsVolumeSlider. Pengubah layout ini adalah cara yang kuat untuk mengatur objek GuiObjects saudara secara otomatis dalam baris horizontal atau kolom vertikal di dalam wadah induknya, termasuk kemampuan untuk menerapkan konsep flex.

Atur sifat berikut untuk UIListLayout baru:
- Padding = 0.06, 0 (6% jarak antara elemen daftar)
- FillDirection = Horizontal (pengaturan elemen dari kiri ke kanan)
- HorizontalFlex = Fill (ubah ukuran elemen secara horizontal untuk mengisi seluruh wadah induk, menimpa lebar yang telah ditentukan)
- VerticalAlignment = Center (meratakan elemen di sepanjang tengah vertikal mereka)
Ikon penggeser
Sebuah ikon sederhana yang mencakup catatan audio dan simbol "burst" membantu pemain mengidentifikasi tujuan penggeser ketika mereka membuka menu pengaturan.

Masukkan ImageLabel ke dalam frame EffectsVolumeSlider dan ganti namanya menjadi Icon. Ikon ini akan membantu pemain memahami aspek pengalaman apa yang dikontrol oleh penggeser.

Dengan Icon terpilih, atur sifat berikut:
- BackgroundTransparency = 1 (sepenuhnya transparan)
- Size = 2.5, 0, 2.5, 0 (250% tinggi dari frame induk setelah rasio aspek dibatasi)
- Image = rbxassetid://90019827067389 (ID aset catatan audio dan simbol "burst")
Masukkan UIAspectRatioConstraint ke dalam Icon dan biarkan propertinya sebagai default (rasio 1:1 lebar terhadap tinggi).


Frame rentang
Langsung di sebelah kanan ikon, bagian interaktif dari penggeser harus terkandung dalam Frame lain.

Masukkan Frame baru ke dalam frame EffectsVolumeSlider dan ganti namanya menjadi SliderFrame. Perhatikan bahwa ini harus menjadi saudara langsung dari pengubah layout UIListLayout.

Dengan SliderFrame terpilih, atur sifat berikut:
- BackgroundColor3 = 0 (hitam)
- BackgroundTransparency = 0.75 (25% opak)
- LayoutOrder = 1
- Size = 1, 0, 1, 0 (100% lebar/tinggi dari frame induk)
Masukkan pengubah berikut ke dalam SliderFrame:
- UIStroke dengan Color diatur ke 0, Thickness diatur ke 3, dan Transparency diatur ke 0.25 (75% opak hitam outline)

Pegangan interaktif
Dengan wadah penggeser dibangun, Anda sekarang dapat membuat pegangan yang dapat diseret bagi pemain untuk berinteraksi selama permainan.

Masukkan Frame baru ke dalam wadah SliderFrame dan ganti namanya menjadi Handle.

Dengan Handle terpilih, atur sifat berikut:
- AnchorPoint = 0.5 (tengah anchor)
- Position = 0.5, 0, 0.5, 0 (tengah horizontal dan vertikal dari frame induk)
- Size = 1.2, 0, 1.2, 0 (120% tinggi dari frame induk setelah rasio aspek dibatasi)
- ZIndex = 3 (lapisan pegangan secara visual di depan elemen slider lainnya)
Masukkan pengubah berikut ke dalam Handle:
- UIAspectRatioConstraint dengan propertinya yang default (rasio 1:1 lebar terhadap tinggi)
Masukkan objek UIDragDetector ke dalam Handle. Objek ini memudahkan dan mendorong interaksi dengan elemen antarmuka pengguna 2D.

Atur sifat berikut untuk UIDragDetector baru:
- ResponseStyle = Scale (bergerak dengan nilai skala dari posisi induk detektor)
Untuk memastikan rentang seret linear pegangan dibatasi pada wadahnya, tautkan BoundingUI ke wadah SliderFrame:
- Pilih UIDragDetector.
- Klik propertinya BoundingUI di jendela Properties.
- Kembali ke jendela Explorer, klik wadah induk SliderFrame.

Tautan properti BoundingUI sekarang mencerminkan wadah SliderFrame:

Jika Anda mencoba pengalaman ini sekarang, Anda akan dapat menyeret pegangan ke kiri dan kanan di dalam wadah induknya:
Isi dalam
Untuk menunjukkan dengan lebih jelas bahwa penggeser mengontrol rentang dari 0% hingga 100%, Anda dapat menambahkan isi dalam ke sisi kiri wadah yang akan disinkronkan dengan posisi variabel pegangan.

Masukkan Frame baru ke dalam wadah SliderFrame dan ganti namanya menjadi InnerFill.

Atur sifat berikut untuk frame InnerFill:
- AnchorPoint = 0, 0.5 (tepi kiri dan tengah vertikal)
- BackgroundColor3 = [0, 150, 255] (biru yang cocok dengan pegangan penggeser)
- BackgroundTransparency = 0.35 (65% opak)
- Position = 0, 0, 0.5, 0
- Size = 0.5, 0, 1, 0 (50% lebar dan 100% tinggi dari frame induk)
- ZIndex = 2 (lapisan secara visual di depan latar belakang/outline frame induk)
Untuk mencocokkan bentuk "pill" dari wadah induk SliderFrame, masukkan pengubah UICorner dan setel propertinya CornerRadius menjadi 0.5, 0.



Duplikat penggeser
Dengan penggeser pertama dibangun, Anda dapat dengan mudah menduplikasinya dan memodifikasi beberapa aspek visual untuk menunjukkan tujuan lain, dalam hal ini level volume audio latar belakang yang disimbolkan oleh ikon not musik.

Pilih objek EffectsVolumeSlider yang sudah selesai.

Duplikat (CtrlD atau ⌘D) dan ganti nama duplikat tersebut menjadi BackgroundVolumeSlider.

Ubah Position dari duplikat menjadi 0.5, 0, 0.7, 0 untuk memindahkannya di bawah penggeser pertama.

Perluas cabang paling atas dari BackgroundVolumeSlider, pilih label gambar Icon, dan ubah propertinya Image menjadi rbxassetid://101125859760167 (ID aset simbol dengan not musik).



Pilih frame InnerFill di dalam SliderFrame dan ubah propertinya BackgroundColor3 menjadi warna magenta yang sama ([255, 0, 125]).



Buat tombol tutup
Elemen terakhir dari menu pengaturan adalah tombol tutup yang memberikan pemain input tambahan untuk menutup menu (tombol SettingsButton di bagian tengah atas akan melayani tujuan yang sama).

Dengan CloseButton terpilih, atur sifat berikut:
- AnchorPoint = 1, 0 (sudut kanan atas)
- BackgroundTransparency = 1 (sepenuhnya transparan)
- Position = 1, -10, 0, 10 (10 piksel inset dari sudut kanan atas)
- Size = 0.15, 0, 0.15, 0 (15% dari tinggi frame setelah rasio aspek dibatasi)
- Image = rbxassetid://5577404210 (ID aset simbol tombol tutup)
- ImageTransparency = 0.25 (75% opak)
Masukkan UIAspectRatioConstraint ke dalam tombol dengan properti default (1:1 lebar terhadap tinggi).


Buat modul kontrol
Pengaturan modul kontrol yang dapat diperluas membuat manajemen UI interaktif lebih efisien daripada skrip individu yang ditempatkan di dalam setiap objek. ModuleScripts memfasilitasi fungsionalitas yang diperluas ini dengan memungkinkan Anda menggunakan kembali kode antar skrip di berbagai sisi batas klien-server atau sisi yang sama dari batas tersebut.
Pengendali objek berstatus
Modul pengendali objek berstatus berikut memungkinkan Anda melampirkan perilaku ke objek UI seperti SettingsButton dan SettingsMenu, dan dengan mudah mengubah/tween antara berbagai status. Untuk membuat modul:
Masukkan ModuleScript ke dalam wadah ReplicatedStorage dan ganti namanya menjadi StatefulObjectController.

Tempelkan kode berikut ke dalam modul:
StatefulObjectControllerlocal TweenService = game:GetService("TweenService")local StatefulObjectController = {}StatefulObjectController.__index = StatefulObjectControllerexport type StateName = stringexport 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.initialStateNamelocal self = setmetatable({states = states,currentStateName = initialStateName,tweens = {},}, StatefulObjectController)-- Buat tween untuk digunakan kembali untuk menghindari pembuatan tween baru setiap kali status diubahfor stateName, state in states doself.tweens[stateName] = TweenService:Create(object, state.transition, state.properties)endself:setState(self.currentStateName)return selfendfunction StatefulObjectController:setState(stateName: StateName)local stateTween: Tween = self.tweens[stateName]if not stateTween thenwarn(string.format("Mencoba untuk mengatur %s ke status '%s' yang tidak dikenal", self.object:GetFullName(), stateName))returnendself.currentStateName = stateName-- Pastikan tween lainnya tidak saling bertentanganfor _, tween in self.tweens dotween:Cancel()endstateTween:Play()endreturn StatefulObjectControllerPenjelasan KodeBaris Tujuan 6‑10 Menentukan dan mengekspor tipe Luau untuk meningkatkan penyelesaian otomatis dan linting saat menggunakan modul ini. 12‑33 Fungsi yang digunakan untuk menginisialisasi dan melampirkan perilaku ke objek UI berstatus, menerima GuiObject sebagai object, tabel status dan data TweenInfo yang sesuai, dan nama status awal. Di dalam fungsi ini, baris 26‑28 membangun Tweens untuk setiap status, dan baris 30 memanggil fungsi setState() modul untuk mengatur objek ke status awal. 35‑50 Fungsi yang digunakan untuk mengatur/mengubah status objek berstatus. Di dalam fungsi ini, baris 42 mengatur currentStateName objek ke status yang sedang diatur, baris 45‑47 membatalkan semua tween yang sedang berjalan untuk mencegah konflik, dan baris 49 menjalankan tween status.
Pengendali penggeser
Modul tambahan menginisialisasi dan mengontrol kedua penggeser volume. Ini juga memungkinkan Anda menghubungkan fungsi callback ke setiap penggeser untuk mendeteksi interaksi pemain dengan penggeser dan menerapkan perubahan yang diinginkan dalam pengalaman.
Masukkan ModuleScript ke dalam wadah ReplicatedStorage dan ganti namanya menjadi SliderController.

Tempelkan kode berikut ke dalam modul:
SliderControllerlocal SliderController = {}SliderController.__index = SliderControllerexport type Value = numberexport type OnChanged = (Value) -> ()function SliderController.hydrate(props: {object: Instance,onChanged: OnChanged,initialValue: Value?})local object, onChanged, initialValue = props.object, props.onChanged, props.initialValuelocal handle = object:FindFirstChild("Handle", true)if not handle thenwarn(string.format("Mencoba untuk menghidrasi penggeser %s tapi tidak bisa menemukan Pegangan", object:GetFullName()))endlocal innerFill = object:FindFirstChild("InnerFill", true)if not innerFill thenwarn(string.format("Mencoba untuk menghidrasi penggeser %s tapi tidak bisa menemukan InnerFill", object:GetFullName()))endlocal dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")if not dragDetector thenwarn(string.format("Mencoba untuk menghidrasi penggeser %s tapi tidak bisa menemukan UIDragDetector", object:GetFullName()))endlocal self = setmetatable({handle = handle,innerFill = innerFill,dragDetector = dragDetector,value = initialValue or 0.5,onChanged = onChanged,}, SliderController)-- Setel nilai awalself:setValue(self.value)-- Hubungkan detektor dengan manipulasi pemainself.dragConnection = dragDetector.DragContinue:Connect(function()self:setValue(handle.Position.X.Scale)end)return selfendfunction SliderController:setValue(value: Value)local clampedValue = math.clamp(value, 0, 1)self.value = clampedValue-- Perbarui posisi pegangan dan ukuran bingkai dalam agar sesuaiself.handle.Position = UDim2.fromScale(clampedValue, 0.5)self.innerFill.Size = UDim2.fromScale(clampedValue, 1)-- Jalankan callback pengguna dengan nilai terbarulocal changeSuccess, changeResult = pcall(self.onChanged, clampedValue)if not changeSuccess thenwarn("Kesalahan dalam callback penggeser:", changeResult)endendreturn SliderControllerPenjelasan KodeBaris Tujuan 7‑46 Fungsi yang digunakan untuk menginisialisasi dan melampirkan perilaku ke elemen penggeser, menerima Frame induk penggeser sebagai object, fungsi callback onChanged untuk memproses perubahan penggeser, dan nilai awal untuk posisi pegangan penggeser. Di dalam fungsi ini, baris 14‑27 mengonfirmasi bahwa elemen pegangan, isi dalam, dan elemen UIDragDetector penggeser ada. Baris 38 memanggil fungsi setValue() modul dan baris 41‑43 menghubungkan acara DragContinue detektor dengan fungsi setValue() modul (lihat baris berikutnya untuk rincian). 48‑61 Fungsi yang digunakan untuk mengatur nilai penggeser. Di dalam fungsi ini, baris 53‑54 memastikan posisi pegangan dan ukuran bingkai dalam disinkronkan, dan baris 57 meneruskan nilai yang telah berubah ke fungsi callback sehingga Anda dapat menggunakan nilai tersebut sesuai kebutuhan.
Buat skrip pengaturan
Dengan tombol pengaturan dan menu pengaturan yang selesai, Anda dapat menghubungkan semuanya dengan satu skrip yang memanfaatkan modul kontrol.
Masukkan skrip LocalScript baru ke dalam HUDContainer dan ganti namanya menjadi SettingsScript untuk menggambarkan tujuannya. Perhatikan bahwa skrip ini harus berada pada level yang sama (saudara) dengan SettingsMenu dan SettingsButton, objek UI tingkat atas yang akan dikelola.

Tempelkan kode berikut ke dalam skrip:
SettingsScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local SoundService = game:GetService("SoundService")local SliderController = require(ReplicatedStorage.SliderController)local StatefulObjectController = require(ReplicatedStorage.StatefulObjectController)local HUDContainer = script.Parent-- Inisialisasi tombol pengaturanlocal 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"})-- Inisialisasi frame menu pengaturanlocal 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"})-- Inisialisasi penggeser volume efeklocal 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 theneffectsAudio.Volume = valueendend,})-- Inisialisasi penggeser volume latar belakanglocal 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 thenbackgroundAudio.Volume = valueendend,})-- Hubungkan tombol dengan interaksi pemainHUDContainer: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)Rujuk ke bagian berikut untuk mengeksplorasi bagaimana skrip memanfaatkan modul kontrol.
Tombol PengaturanBaris 10-27 menginisialisasi dan melampirkan perilaku ke tombol pengaturan sebagai berikut:
Baris Tujuan 10‑11 Sebuah referensi lokal settingsButton diumumkan dan dihidrat dengan fungsi StatefulObjectController.hydrate(), dan objek SettingsButton dalam HUDContainer dirujuk sebagai objek untuk dihidrasi. 12‑25 Sebuah tabel states dilewatkan dengan dua status unik, menuOpen dan menuClosed. Setiap status berisi transisi untuk mendeklarasikan (melalui TweenInfo) bagaimana status tertentu akan mencapai properti target yang didefinisikan dalam tabel properties. Dalam hal ini, menuOpen mendeklarasikan perubahan status menjadi 45° untuk Rotation tombol dengan tween Exponential selama ½ detik, sementara menuClosed secara efektif mengembalikan tombol ke rotasi defaultnya 0. 26 Status awal tombol diatur ke menuClosed (ini bisa diatur ke nama status apa pun di dalam tabel states). Lebih jauh ke bawah dalam skrip (baris 76-86), tombol-tombol dihubungkan dengan interaksi pemain untuk memicu perubahan status UI:
Baris Tujuan 76‑82 SettingsButton dihubungkan ke peristiwa Activated dari kelas GuiButton untuk memanggil sebuah fungsi anonim. Di dalam fungsi anonim ini, baris 77‑79 mengubah variabel targetState antara menuOpen dan menuClosed. Baris 80 kemudian memanggil setState() untuk mengatur status tombol ke targetState dan baris 81 melakukan hal yang sama untuk SettingsMenu sehingga menu itu terbuka atau tertutup dengan aktivasi SettingsButton. 83‑86 CloseButton dihubungkan ke peristiwa Activated untuk memanggil sebuah fungsi anonim yang mengatur status baik SettingsButton maupun SettingsMenu ke menuClosed. Menu PengaturanBaris 30-49 menginisialisasi dan melampirkan perilaku ke menu pengaturan sebagai berikut:
Baris Tujuan 30‑31 Sebuah referensi lokal settingsMenu diumumkan dan dihidrat dengan fungsi StatefulObjectController.hydrate() dan objek frame SettingsMenu dalam HUDContainer dirujuk sebagai objek untuk dihidrasi. 32‑46 Mirip dengan tombol pengaturan, sebuah tabel states dilewatkan dengan dua status unik, menuOpen dan menuClosed. Di sini, menuOpen mendeklarasikan perubahan status ke UDim2.fromScale(0.5, 0.5) untuk Position frame dengan tween Bounce selama ½ detik, serta Visible ke true. Sebaliknya, menuClosed mendeklarasikan perubahan status posisi ke UDim2.fromScale(0.5, 0.4) dan Visible ke false, tetapi TweenInfo dengan durasi 0 di baris 41 secara efektif membuat perubahan status terjadi secara instan. 48 Status awal frame diatur ke menuClosed. Lebih jauh ke bawah dalam skrip (baris 76-86), menu pengaturan dihubungkan dengan interaksi pemain:
Baris Tujuan 81 Menetapkan status yang sama untuk SettingsMenu agar sinkron dengan aktivasi SettingsButton. 85 Menetapkan status SettingsMenu ke menuClosed saat CloseButton diaktifkan. Penggeser VolumeBaris 51-73 menginisialisasi dan melampirkan perilaku ke EffectsVolumeSlider dan BackgroundVolumeSlider sebagai berikut:
Baris Tujuan 52 Menetapkan referensi lokal ke SoundGroup Effects dalam SoundService. Sebuah SoundGroup memungkinkan Anda mengaitkan beberapa Sounds dan mengontrol volume setiap suara dalam grup melalui properti Volume grup tersebut. 53‑54 Sebuah referensi lokal effectsVolumeSlider diumumkan dan dihidrat dengan fungsi SliderController.hydrate() dan frame EffectsVolumeSlider dalam HUDContainer ⟩ SettingsMenu dirujuk sebagai objek untuk dihidrasi. Perhatikan bahwa parameter kedua true untuk FindFirstChild() memberi tahu metode untuk mencari secara rekursif turun cabang HUDContainer untuk menemukan EffectsVolumeSlider. 55 Nilai awal penggeser diatur ke Volume saat ini dari grup Effects, atau 0.5 sebagai fallback. 56‑60 Menetapkan fungsi callback untuk menerapkan perubahan nilai penggeser ke volume grup suara Effects. 64‑73 Essentially the same as lines 52-61, except to hydrate the BackgroundVolumeSlider frame within HUDContainer ⟩ SettingsMenu and apply slider value changes to the volume of the Background sound group.
Dengan SettingsScript ditempatkan, pengalaman sekarang menawarkan contoh UI interaktif yang sepenuhnya beroperasi yang menghubungkan serangkaian objek UI terkait dengan interaksi pemain.






