Memulai
Tutorial menengah

Buat UI interaktif

*Konten ini diterjemahkan menggunakan AI (Beta) dan mungkin mengandung kesalahan. Untuk melihat halaman ini dalam bahasa Inggris, klik di sini.

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.

Tampilan dalam permainan menunjukkan tombol pengaturan dan menu pengaturan dengan penggeser volume.

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:

  1. Buka template UI Fundamentals - Meter HUD di Studio.

  2. Dari menu Test di Studio, aktifkan Emulator Perangkat.

  3. 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.

    Opsi pengaturan Emulator Perangkat yang ditunjukkan di bagian atas jendela tampilan.

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.

Komponen Roblox yang digunakan untuk tombol pengaturan.

Untuk membangun tombol pengaturan:

  1. Di jendela Explorer, temukan HUDContainer di dalam StarterGui.

    Jendela Explorer menunjukkan HUDContainer yang dipilih.
  2. Masukkan ImageButton ke dalam HUDContainer dan ganti namanya menjadi SettingsButton.

    Jendela Explorer menunjukkan ImageButton baru yang dimasukkan dan diganti namanya menjadi SettingsButton. ImageButton baru di viewport.
  3. 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")
  4. Masukkan UIAspectRatioConstraint ke dalam tombol dengan properti default (rasio 1:1 lebar terhadap tinggi).

    Jendela Explorer menunjukkan UIAspectRatioConstraint baru yang dimasukkan ke dalam tombol SettingsButton.
  5. Untuk membatasi tinggi piksel maksimum tombol, masukkan UISizeConstraint dan set fitur MaxSize ke inf, 44.

    Jendela Explorer menunjukkan UISizeConstraint baru yang dimasukkan ke dalam tombol SettingsButton.
    Jendela Properties menunjukkan nilai yang diharapkan untuk UISizeConstraint baru.
    Tombol pengaturan final di tengah atas layar.

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.

Komponen dasar yang digunakan untuk menu pengaturan.

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.

  1. Masukkan Frame ke dalam HUDContainer dan ganti namanya menjadi SettingsMenu.

    Jendela Explorer menunjukkan frame baru yang dimasukkan dan diganti namanya menjadi SettingsMenu.
  2. Dengan SettingsMenu terpilih, tetapkan properti berikut:

    Frame yang dipindahkan, diubah ukurannya, dan dihias dengan latar belakang navy biru transparan.
  3. Masukkan UIAspectRatioConstraint ke dalam SettingsMenu dan atur properti AspectRatio menjadi 2.5. (2.5:1 lebar terhadap tinggi).

    Jendela Explorer menunjukkan UISizeConstraint baru yang dimasukkan ke dalam frame SettingsMenu.
    Jendela Properties menunjukkan nilai yang diharapkan untuk UISizeConstraint baru.
  4. Masukkan pengubah UICorner ke dalam SettingsMenu dan atur properti CornerRadius ke 0.1, 0.

    Jendela Explorer menunjukkan UICorner baru yang dimasukkan ke dalam frame SettingsMenu.
    Jendela Properties menunjukkan nilai yang diharapkan untuk pengubah UICorner baru.
  5. Untuk membatasi lebar dan tinggi piksel dari SettingsMenu, masukkan UISizeConstraint. Atur MaxSize ke 800, inf dan MinSize ke 350, 0.

    Jendela Explorer menunjukkan UISizeConstraint baru yang dimasukkan ke dalam frame SettingsMenu.
    Jendela Properties menunjukkan nilai yang diharapkan untuk UISizeConstraint baru.
    Frame dihias dengan sudut bulat.

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:

  1. Masukkan Frame baru ke dalam wadah SettingsMenu dan ganti namanya menjadi EffectsVolumeSlider.

    Jendela Explorer menunjukkan frame baru yang dimasukkan ke dalam frame SettingsMenu, diganti namanya menjadi EffectsVolumeSlider.
  2. 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)

      Frame kosong dimasukkan untuk mengandung elemen penggeser.
  3. 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.

    Jendela Explorer menunjukkan UIListLayout baru yang dimasukkan ke dalam frame EffectsVolumeSlider.
  4. Atur sifat berikut untuk UIListLayout baru:

Ikon penggeser

Sebuah ikon sederhana yang mencakup catatan audio dan simbol "burst" membantu pemain mengidentifikasi tujuan penggeser ketika mereka membuka menu pengaturan.

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

    Jendela Explorer menunjukkan ImageLabel yang dimasukkan ke dalam frame EffectsVolumeSlider.
  2. 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")
  3. Masukkan UIAspectRatioConstraint ke dalam Icon dan biarkan propertinya sebagai default (rasio 1:1 lebar terhadap tinggi).

    Jendela Explorer menunjukkan UIAspectRatioConstraint yang dimasukkan ke dalam ImageLabel. Ikon final di menu pengaturan.

Frame rentang

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

Ukuran dan posisi target dari bagian interaktif penggeser.
  1. Masukkan Frame baru ke dalam frame EffectsVolumeSlider dan ganti namanya menjadi SliderFrame. Perhatikan bahwa ini harus menjadi saudara langsung dari pengubah layout UIListLayout.

    Jendela Explorer menunjukkan frame anak yang dimasukkan ke dalam frame EffectsVolumeSlider.
  2. Dengan SliderFrame terpilih, atur sifat berikut:

  3. Masukkan pengubah berikut ke dalam SliderFrame:

    Frame penggeser yang diposisikan di sebelah kanan ikon.

Pegangan interaktif

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

Pegangan penggeser interaktif diposisikan dalam frame rentang.
  1. Masukkan Frame baru ke dalam wadah SliderFrame dan ganti namanya menjadi Handle.

    Jendela Explorer menunjukkan frame anak yang dimasukkan ke dalam frame SliderFrame dan diganti namanya menjadi Handle.
  2. 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)
  3. Masukkan pengubah berikut ke dalam Handle:

  4. Masukkan objek UIDragDetector ke dalam Handle. Objek ini memudahkan dan mendorong interaksi dengan elemen antarmuka pengguna 2D.

    Jendela Explorer menunjukkan UIDragDetector yang dimasukkan ke dalam frame Handle.
  5. Atur sifat berikut untuk UIDragDetector baru:

  6. Untuk memastikan rentang seret linear pegangan dibatasi pada wadahnya, tautkan BoundingUI ke wadah SliderFrame:

    1. Klik propertinya BoundingUI di jendela Properties.
    2. Kembali ke jendela Explorer, klik wadah induk SliderFrame.
    Diagram menunjukkan proses menautkan properti BoundingUI detektor ke wadah SliderFrame.

    Tautan properti BoundingUI sekarang mencerminkan wadah SliderFrame:

    Jendela Properties menunjukkan properti BoundingUI detektor yang ditautkan ke 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.

Bagian isi dalam penggeser dimasukkan ke dalam SliderFrame.
  1. Masukkan Frame baru ke dalam wadah SliderFrame dan ganti namanya menjadi InnerFill.

    Jendela Explorer menunjukkan frame anak yang dimasukkan ke dalam frame SliderFrame dan diganti namanya menjadi InnerFill.
  2. 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)
  3. Untuk mencocokkan bentuk "pill" dari wadah induk SliderFrame, masukkan pengubah UICorner dan setel propertinya CornerRadius menjadi 0.5, 0.

    Jendela Explorer menunjukkan pengubah UICorner yang dimasukkan ke dalam frame InnerFill.
    Jendela Properties menunjukkan nilai yang diharapkan untuk pengubah UICorner baru.
    Frame InnerFill dihiasi dengan latar belakang biru dan sudut bulat.

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.

Posisi target dari penggeser audio latar belakang.
  1. Pilih objek EffectsVolumeSlider yang sudah selesai.

    Jendela Explorer menunjukkan EffectsVolumeSlider yang sudah selesai dipilih.
  2. Duplikat (CtrlD atau D) dan ganti nama duplikat tersebut menjadi BackgroundVolumeSlider.

    Jendela Explorer menunjukkan penggeser yang diduplikasi diganti nama menjadi BackgroundVolumeSlider.
  3. Ubah Position dari duplikat menjadi 0.5, 0, 0.7, 0 untuk memindahkannya di bawah penggeser pertama.

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

    Jendela Explorer menunjukkan label Icon dalam BackgroundVolumeSlider.
    Jendela Properties menunjukkan nilai yang diharapkan untuk label Icon.
    BackgroundVolumeSlider dengan gambar ikon yang dimodifikasi.
  5. Perluas cabang SliderFrameHandle, pilih pengubah UIStroke di dalamnya, dan atur propertinya Color menjadi [255, 0, 125] (magenta).

    Jendela Explorer menunjukkan UIStroke yang ada dalam pegangan BackgroundVolumeSlider.
    Jendela Properties menunjukkan nilai yang diharapkan untuk pengubah UIStroke.
    BackgroundVolumeSlider dengan gambar ikon yang dimodifikasi.
  6. Pilih frame InnerFill di dalam SliderFrame dan ubah propertinya BackgroundColor3 menjadi warna magenta yang sama ([255, 0, 125]).

    Jendela Explorer menunjukkan frame InnerFill di dalam wadah SliderFrame BackgroundVolumeSlider.
    Jendela Properties menunjukkan nilai yang diharapkan untuk frame InnerFill.
    BackgroundVolumeSlider dengan warna InnerFill yang dimodifikasi.

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).

Menu pengaturan dengan tombol tutup yang ditunjukkan di sudut kanan atas.
  1. Masukkan ImageButton baru ke dalam wadah SettingsMenu dan ganti namanya menjadi CloseButton.

    Jendela Explorer menunjukkan ImageButton baru yang dimasukkan ke dalam SettingsMenu dan diganti namanya menjadi CloseButton. ImageButton kosong diposisikan di sudut kiri atas menu pengaturan.
  2. Dengan CloseButton terpilih, atur sifat berikut:

  3. Masukkan UIAspectRatioConstraint ke dalam tombol dengan properti default (1:1 lebar terhadap tinggi).

    Jendela Explorer menunjukkan UIAspectRatioConstraint yang dimasukkan ke dalam tombol CloseButton. Tombol tutup final di sudut kanan atas menu pengaturan.

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:

  1. Masukkan ModuleScript ke dalam wadah ReplicatedStorage dan ganti namanya menjadi StatefulObjectController.

    Jendela Explorer menunjukkan modul StatefulObjectController di dalam wadah ReplicatedStorage.
  2. Tempelkan kode berikut ke dalam modul:

    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)
    -- Buat tween untuk digunakan kembali untuk menghindari pembuatan tween baru setiap kali status diubah
    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("Mencoba untuk mengatur %s ke status '%s' yang tidak dikenal", self.object:GetFullName(), stateName))
    return
    end
    self.currentStateName = stateName
    -- Pastikan tween lainnya tidak saling bertentangan
    for _, tween in self.tweens do
    tween:Cancel()
    end
    stateTween:Play()
    end
    return StatefulObjectController
    BarisTujuan
    610Menentukan dan mengekspor tipe Luau untuk meningkatkan penyelesaian otomatis dan linting saat menggunakan modul ini.
    1233Fungsi 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 2628 membangun Tweens untuk setiap status, dan baris 30 memanggil fungsi setState() modul untuk mengatur objek ke status awal.
    3550Fungsi yang digunakan untuk mengatur/mengubah status objek berstatus. Di dalam fungsi ini, baris 42 mengatur currentStateName objek ke status yang sedang diatur, baris 4547 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.

  1. Masukkan ModuleScript ke dalam wadah ReplicatedStorage dan ganti namanya menjadi SliderController.

    Jendela Explorer menunjukkan modul SliderController di dalam wadah ReplicatedStorage.
  2. Tempelkan kode berikut ke dalam modul:

    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("Mencoba untuk menghidrasi penggeser %s tapi tidak bisa menemukan Pegangan", object:GetFullName()))
    end
    local innerFill = object:FindFirstChild("InnerFill", true)
    if not innerFill then
    warn(string.format("Mencoba untuk menghidrasi penggeser %s tapi tidak bisa menemukan InnerFill", object:GetFullName()))
    end
    local dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
    if not dragDetector then
    warn(string.format("Mencoba untuk menghidrasi penggeser %s tapi tidak bisa menemukan UIDragDetector", object:GetFullName()))
    end
    local self = setmetatable({
    handle = handle,
    innerFill = innerFill,
    dragDetector = dragDetector,
    value = initialValue or 0.5,
    onChanged = onChanged,
    }, SliderController)
    -- Setel nilai awal
    self:setValue(self.value)
    -- Hubungkan detektor dengan manipulasi pemain
    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
    -- Perbarui posisi pegangan dan ukuran bingkai dalam agar sesuai
    self.handle.Position = UDim2.fromScale(clampedValue, 0.5)
    self.innerFill.Size = UDim2.fromScale(clampedValue, 1)
    -- Jalankan callback pengguna dengan nilai terbaru
    local changeSuccess, changeResult = pcall(self.onChanged, clampedValue)
    if not changeSuccess then
    warn("Kesalahan dalam callback penggeser:", changeResult)
    end
    end
    return SliderController
    BarisTujuan
    746Fungsi 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 1427 mengonfirmasi bahwa elemen pegangan, isi dalam, dan elemen UIDragDetector penggeser ada. Baris 38 memanggil fungsi setValue() modul dan baris 4143 menghubungkan acara DragContinue detektor dengan fungsi setValue() modul (lihat baris berikutnya untuk rincian).
    4861Fungsi yang digunakan untuk mengatur nilai penggeser. Di dalam fungsi ini, baris 5354 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.

  1. 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.

    Jendela Explorer menunjukkan skrip SettingsScript di dalam wadah HUDContainer.
  2. Tempelkan kode berikut ke dalam skrip:

    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
    -- Inisialisasi tombol pengaturan
    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"
    })
    -- Inisialisasi frame menu pengaturan
    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"
    })
    -- Inisialisasi penggeser volume efek
    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,
    })
    -- Inisialisasi penggeser volume latar belakang
    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,
    })
    -- Hubungkan tombol dengan interaksi pemain
    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. Rujuk ke bagian berikut untuk mengeksplorasi bagaimana skrip memanfaatkan modul kontrol.

    Baris 10-27 menginisialisasi dan melampirkan perilaku ke tombol pengaturan sebagai berikut:

    BarisTujuan
    1011Sebuah referensi lokal settingsButton diumumkan dan dihidrat dengan fungsi StatefulObjectController.hydrate(), dan objek SettingsButton dalam HUDContainer dirujuk sebagai objek untuk dihidrasi.
    1225Sebuah 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.
    26Status 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:

    BarisTujuan
    7682SettingsButton dihubungkan ke peristiwa Activated dari kelas GuiButton untuk memanggil sebuah fungsi anonim. Di dalam fungsi anonim ini, baris 7779 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.
    8386CloseButton dihubungkan ke peristiwa Activated untuk memanggil sebuah fungsi anonim yang mengatur status baik SettingsButton maupun SettingsMenu ke menuClosed.

    Baris 30-49 menginisialisasi dan melampirkan perilaku ke menu pengaturan sebagai berikut:

    BarisTujuan
    3031Sebuah referensi lokal settingsMenu diumumkan dan dihidrat dengan fungsi StatefulObjectController.hydrate() dan objek frame SettingsMenu dalam HUDContainer dirujuk sebagai objek untuk dihidrasi.
    3246Mirip 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.
    48Status awal frame diatur ke menuClosed.

    Lebih jauh ke bawah dalam skrip (baris 76-86), menu pengaturan dihubungkan dengan interaksi pemain:

    BarisTujuan
    81Menetapkan status yang sama untuk SettingsMenu agar sinkron dengan aktivasi SettingsButton.
    85Menetapkan status SettingsMenu ke menuClosed saat CloseButton diaktifkan.

    Baris 51-73 menginisialisasi dan melampirkan perilaku ke EffectsVolumeSlider dan BackgroundVolumeSlider sebagai berikut:

    BarisTujuan
    52Menetapkan 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.
    5354Sebuah 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.
    55Nilai awal penggeser diatur ke Volume saat ini dari grup Effects, atau 0.5 sebagai fallback.
    5660Menetapkan fungsi callback untuk menerapkan perubahan nilai penggeser ke volume grup suara Effects.
    6473Essentially 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.

©2026 Roblox Corporation. Roblox, logo Roblox, dan Powering Imagination termasuk dalam merek dagang kami yang terdaftar dan tidak terdaftar di AS dan negara lainnya.