A HUD (Heads-Up Display) dalam permainan Anda biasanya menampilkan elemen UI non-interaktif seperti meter kesehatan yang ditunjukkan dalam Buat meter HUD. Selain itu, hampir setiap permainan memerlukan UI interaktif seperti tombol yang merespons aktivasi pemain, beranimasi saat diaktifkan, tween masuk/keluar menu dengan kontrol interaktif lainnya, dll.

Menggunakan UI Fundamentals - Meter HUD sebagai tempat awal dan UI Fundamentals - Interaktivitas sebagai referensi yang sudah selesai, tutorial ini menunjukkan:
- Cara memposisikan tombol pengaturan di sepanjang tepi atas layar.
- Desain menu pengaturan yang berisi penggeser interaktif yang dapat diseret.
- Penggunaan ModuleScripts untuk membentuk modul "pengontrol" untuk kontrol yang dapat diperluas dari objek UI dengan deklarasi yang memiliki status.
- Cara menghubungkan tombol ke aktivasi pemain untuk mengalihkan menu pengaturan masuk/keluar.
- Cara menghubungkan penggeser UI yang dapat diseret untuk menyesuaikan volume efek suara dan suasana latar belakang secara terpisah.
Aktifkan Emulator Perangkat
Seperti yang dicatat dalam Buat meter HUD, ponsel dan tablet memiliki ruang layar paling sedikit, jadi penting agar elemen UI Anda muat di layar yang lebih kecil dan terlihat jelas bagi pemain. Jika Anda belum melakukannya, aktifkan Emulator Perangkat di Studio:
Buka template UI Fundamentals - Meter HUD di Studio.
Dari menu Uji di Studio, aktifkan Emulator Perangkat.
Dari bilah tepat di atas viewport utama, pilih emulasi ponsel seperti iPhone X atau Samsung Galaxy A51. Kemudian, atur 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 acara Activated multi-platform yang dipicu saat tombol diklik atau diketuk. Kelas GuiButton memiliki dua variasi, TextButton dan ImageButton, dan tutorial ini menggunakan ImageButton berbentuk "gear" untuk mengalihkan menu pengaturan terbuka atau tertutup.

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

Dengan tombol baru yang dipilih, atur 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 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 atur MaxSize ke inf, 44.



Buat menu pengaturan
Tombol pengaturan baru akan diprogram untuk mengalihkan menu pengaturan terbuka dan tertutup, memberikan akses on-demand kepada pemain ke pengaturan atau informasi lainnya. Dalam tutorial ini, menu 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, membuatnya mudah dikelola sebagai objek yang memiliki status yang bereaksi terhadap input dengan cara yang berbeda tergantung pada status saat ini.
Masukkan Frame ke dalam HUDContainer dan ganti namanya menjadi SettingsMenu.

Dengan SettingsMenu yang dipilih, atur properti berikut:
- AnchorPoint = 0.5 (tengah jangkar)
- 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 area layar yang terpotong)

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


Masukkan modifikasi UICorner ke dalam SettingsMenu dan atur 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 didukung oleh UIDragDetector, objek yang nyaman yang memfasilitasi interaksi dengan elemen antarmuka pengguna 2D.
Untuk membuat wadah induk untuk penggeser pertama:
Masukkan Frame baru ke dalam wadah SettingsMenu dan ganti namanya menjadi EffectsVolumeSlider.

Dengan frame EffectsVolumeSlider yang dipilih, atur properti berikut:
AnchorPoint = 0.5 (tengah jangkar)
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. Modifikasi tata letak ini adalah cara yang kuat untuk secara otomatis mengatur GuiObjects saudara ke dalam baris horizontal atau kolom vertikal dalam wadah induknya, termasuk kemampuan untuk menerapkan konsep flex.

Atur properti berikut untuk UIListLayout baru:
- Padding = 0.06, 0 (padding 6% 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 ditentukan)
- VerticalAlignment = Center (rata tengah elemen secara vertikal)
Ikon penggeser
Sebuah ikon sederhana yang mencakup catatan audio dan simbol "ledakan" membantu pemain mengidentifikasi tujuan penggeser saat mereka membuka menu pengaturan.

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

Dengan Icon yang dipilih, atur properti berikut:
- BackgroundTransparency = 1 (sepenuhnya transparan)
- Size = 2.5, 0, 2.5, 0 (250% tinggi frame induk setelah rasio aspek dibatasi)
- Image = rbxassetid://90019827067389 (ID aset catatan audio dan simbol "ledakan")
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 ditempatkan dalam Frame lain.

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

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

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

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

Dengan Handle yang dipilih, atur properti berikut:
- AnchorPoint = 0.5 (tengah jangkar)
- 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 penggeser lainnya)
Masukkan modifikasi berikut ke dalam Handle:
- UIAspectRatioConstraint dengan properti defaultnya (rasio 1:1 lebar terhadap tinggi)
Masukkan objek UIDragDetector ke dalam Handle. Objek yang nyaman ini memfasilitasi dan mendorong interaksi dengan elemen antarmuka pengguna 2D.

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

Properti tautan BoundingUI sekarang mencerminkan wadah SliderFrame:

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

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

Atur properti 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 isi/outline frame induk)
Untuk mencocokkan bentuk "pil" dari wadah induk SliderFrame, masukkan modifikasi UICorner dan atur properti CornerRadius ke 0.5, 0.



Duplikat penggeser
Dengan penggeser pertama yang 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 telah selesai.

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

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

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



Pilih frame InnerFill di dalam SliderFrame dan ubah properti 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 tengah atas akan melayani tujuan yang sama).

Dengan CloseButton yang dipilih, atur properti berikut:
- AnchorPoint = 1, 0 (sudut kanan atas)
- BackgroundTransparency = 1 (sepenuhnya transparan)
- Position = 1, -10, 0, 10 (10 piksel 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 (rasio 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 dapat diperluas ini dengan memungkinkan Anda menggunakan kembali kode antara skrip di sisi batas klien-server yang berbeda atau di sisi yang sama dari batas tersebut.
Pengontrol objek yang memiliki status
Modul pengontrol objek yang memiliki status berikut memungkinkan Anda melampirkan perilaku ke objek UI seperti SettingsButton dan SettingsMenu, dan dengan mudah mengalihkan/tween antara berbagai status. Untuk membuat modul:
Masukkan ModuleScript ke dalam wadah ReplicatedStorage dan ganti namanya menjadi StatefulObjectController.

Tempelkan kode berikut di 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 membuat 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 mengatur %s ke status tidak dikenal '%s'", self.object:GetFullName(), stateName))returnendself.currentStateName = stateName-- Pastikan tween lain tidak bertentanganfor _, tween in self.tweens dotween:Cancel()endstateTween:Play()endreturn StatefulObjectControllerPenjelasan KodeBaris Tujuan 6‑10 Menentukan dan mengekspor tipe Luau untuk meningkatkan autocompletion dan linting saat menggunakan modul ini. 12‑33 Fungsi yang digunakan untuk menginisialisasi dan melampirkan perilaku ke objek UI yang memiliki status, menerima GuiObject sebagai object, tabel status dan data TweenInfo masing-masing, serta 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 yang memiliki status. Di dalam fungsi ini, baris 42 mengatur currentStateName objek ke status yang sedang diatur, baris 45‑47 membatalkan tween yang sedang berjalan untuk mencegah konflik, dan baris 49 mengeksekusi tween status.
Pengontrol penggeser
Modul tambahan menginisialisasi dan mengontrol dua penggeser volume. Ini juga memungkinkan Anda menghubungkan fungsi callback ke setiap penggeser untuk mendeteksi interaksi pemain dengan penggeser dan menerapkan perubahan yang diinginkan dalam permainan.
Masukkan ModuleScript ke dalam wadah ReplicatedStorage dan ganti namanya menjadi SliderController.

Tempelkan kode berikut di 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 menghidupkan penggeser %s tetapi tidak dapat menemukan Handle", object:GetFullName()))endlocal innerFill = object:FindFirstChild("InnerFill", true)if not innerFill thenwarn(string.format("Mencoba menghidupkan penggeser %s tetapi tidak dapat menemukan InnerFill", object:GetFullName()))endlocal dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")if not dragDetector thenwarn(string.format("Mencoba menghidupkan penggeser %s tetapi tidak dapat menemukan UIDragDetector", object:GetFullName()))endlocal self = setmetatable({handle = handle,innerFill = innerFill,dragDetector = dragDetector,value = initialValue or 0.5,onChanged = onChanged,}, SliderController)-- Atur nilai awalself:setValue(self.value)-- Hubungkan detektor ke 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 frame dalam untuk mencocokkanself.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 memastikan bahwa pegangan, isi dalam, dan elemen UIDragDetector penggeser ada. Baris 38 memanggil fungsi setValue() modul dan baris 41‑43 menghubungkan acara DragContinue detektor ke fungsi setValue() modul (lihat baris berikutnya untuk detail). 48‑61 Fungsi yang digunakan untuk mengatur nilai penggeser. Di dalam fungsi ini, baris 53‑54 memastikan posisi pegangan dan ukuran isi dalam disinkronkan, dan baris 57 meneruskan nilai yang diubah ke fungsi callback sehingga Anda dapat memanfaatkan nilai tersebut sesuai kebutuhan.
Buat skrip pengaturan
Dengan tombol pengaturan dan menu pengaturan yang telah selesai, Anda dapat menghubungkan semuanya dengan satu skrip yang memanfaatkan modul kontrol.
Masukkan 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 dikelolanya.

Tempelkan kode berikut di 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 ke 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 bagian berikut untuk menjelajahi 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 dideklarasikan dan dihidupkan dengan fungsi StatefulObjectController.hydrate(), dan tombol SettingsButton di dalam HUDContainer dirujuk sebagai objek untuk dihidupkan. 12‑25 Sebuah tabel states diteruskan 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 yaitu 0. 26 Status awal tombol diatur ke menuClosed (ini bisa diatur ke nama status apa pun dalam tabel states). Lebih jauh ke bawah dalam skrip (baris 76-86), tombol dihubungkan ke interaksi pemain untuk memicu perubahan status UI:
Baris Tujuan 76‑82 SettingsButton dihubungkan ke acara Activated dari kelas GuiButton untuk memanggil fungsi anonim. Di dalam fungsi anonim, baris 77‑79 mengalihkan 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 dapat dibuka atau ditutup dengan aktivasi SettingsButton. 83‑86 CloseButton dihubungkan ke acara Activated untuk memanggil fungsi anonim yang mengatur status SettingsButton dan SettingsMenu ke menuClosed. Menu PengaturanBaris 30-49 menginisialisasi dan melampirkan perilaku ke menu pengaturan sebagai berikut:
Baris Tujuan 30‑31 Sebuah referensi lokal settingsMenu dideklarasikan dan dihidupkan dengan fungsi StatefulObjectController.hydrate() dan frame SettingsMenu di dalam HUDContainer dirujuk sebagai objek untuk dihidupkan. 32‑46 Mirip dengan tombol pengaturan, sebuah tabel states diteruskan dengan dua status unik, menuOpen dan menuClosed. Di sini, menuOpen mendeklarasikan perubahan status menjadi UDim2.fromScale(0.5, 0.5) untuk Position frame dengan tween Bounce selama ½ detik, serta status Visible menjadi true. Sebaliknya, menuClosed mendeklarasikan perubahan status posisi menjadi UDim2.fromScale(0.5, 0.4) dan Visible menjadi false, tetapi TweenInfo dengan durasi 0 pada 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 ke interaksi pemain:
Baris Tujuan 81 Menetapkan targetState yang sama untuk SettingsMenu untuk disinkronkan 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 di dalam SoundService. Sebuah SoundGroup memungkinkan Anda mengaitkan beberapa Sounds dan mengontrol volume setiap suara dalam grup melalui properti Volume grup. 53‑54 Sebuah referensi lokal effectsVolumeSlider dideklarasikan dan dihidupkan dengan fungsi SliderController.hydrate() dan frame EffectsVolumeSlider di dalam HUDContainer ⟩ SettingsMenu dirujuk sebagai objek untuk dihidupkan. Perhatikan bahwa parameter kedua true untuk FindFirstChild() memberi tahu metode untuk mencari secara rekursif ke bawah cabang HUDContainer untuk menemukan EffectsVolumeSlider. 55 Nilai awal penggeser diatur ke Volume saat ini dari grup suara Effects, atau 0.5 sebagai cadangan. 56‑60 Menetapkan fungsi callback untuk menerapkan perubahan nilai penggeser ke volume grup suara Effects. 64‑73 Pada dasarnya sama dengan baris 52-61, kecuali untuk menghidupkan frame BackgroundVolumeSlider di dalam HUDContainer ⟩ SettingsMenu dan menerapkan perubahan nilai penggeser ke volume grup suara Background.
Dengan SettingsScript di tempat, permainan sekarang menawarkan contoh UI interaktif yang sepenuhnya beroperasi yang menghubungkan serangkaian objek UI terkait ke interaksi pemain.






