Buat UI interaktif

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

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.

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 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:

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

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

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

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

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.

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

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, membuatnya mudah dikelola sebagai objek yang memiliki status yang bereaksi terhadap input dengan cara yang berbeda tergantung pada status 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 yang dipilih, atur properti berikut:

    Frame dipindahkan, diubah ukurannya, dan diberi gaya dengan latar belakang biru navy transparan.
  3. Masukkan UIAspectRatioConstraint ke dalam SettingsMenu dan atur properti AspectRatio ke 2.5. (rasio 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 modifikasi UICorner ke dalam SettingsMenu dan atur CornerRadius ke 0.1, 0.

    Jendela Explorer menunjukkan UICorner baru yang dimasukkan ke dalam frame SettingsMenu.
    Jendela Properties menunjukkan nilai yang diharapkan untuk modifikasi 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 diberi gaya dengan sudut membulat.

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:

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

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

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

Ikon penggeser

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

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

    Jendela Explorer menunjukkan ImageLabel yang dimasukkan ke dalam frame EffectsVolumeSlider.
  2. 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")
  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 yang telah diselesaikan di menu pengaturan.

Frame rentang

Langsung di sebelah kanan ikon, bagian interaktif dari penggeser harus ditempatkan 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 modifikasi tata letak UIListLayout.

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

  3. Masukkan modifikasi berikut ke dalam SliderFrame:

    Frame penggeser diposisikan di sebelah kanan ikon.

Pegangan interaktif

Dengan wadah penggeser yang dibangun, Anda sekarang dapat membuat pegangan yang dapat diseret untuk pemain 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 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)
  3. Masukkan modifikasi berikut ke dalam Handle:

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

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

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

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

    Properti tautan BoundingUI sekarang mencerminkan wadah SliderFrame:

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

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 properti berikut untuk frame InnerFill:

  3. Untuk mencocokkan bentuk "pil" dari wadah induk SliderFrame, masukkan modifikasi UICorner dan atur properti CornerRadius ke 0.5, 0.

    Jendela Explorer menunjukkan modifikasi UICorner yang dimasukkan ke dalam frame InnerFill.
    Jendela Properties menunjukkan nilai yang diharapkan untuk UICorner baru.
    Frame InnerFill diberi gaya dengan latar belakang biru dan sudut membulat.

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.

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

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

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

    BackgroundVolumeSlider diposisikan di bawah EffectsVolumeSlider.
  4. Perluas cabang tingkat atas dari BackgroundVolumeSlider, pilih label gambar Icon, dan ubah properti 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 modifikasi UIStroke di dalamnya, dan atur properti Color menjadi [255, 0, 125] (magenta).

    Jendela Explorer menunjukkan modifikasi UIStroke di dalam pegangan BackgroundVolumeSlider.
    Jendela Properties menunjukkan nilai yang diharapkan untuk modifikasi UIStroke.
    BackgroundVolumeSlider dengan gambar ikon yang dimodifikasi.
  6. Pilih frame InnerFill di dalam SliderFrame dan ubah properti 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 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 yang dipilih, atur properti berikut:

  3. Masukkan UIAspectRatioConstraint ke dalam tombol dengan properti default (rasio 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 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:

  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 di 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 membuat 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 mengatur %s ke status tidak dikenal '%s'", self.object:GetFullName(), stateName))
    return
    end
    self.currentStateName = stateName
    -- Pastikan tween lain tidak bertentangan
    for _, tween in self.tweens do
    tween:Cancel()
    end
    stateTween:Play()
    end
    return StatefulObjectController
    BarisTujuan
    610Menentukan dan mengekspor tipe Luau untuk meningkatkan autocompletion dan linting saat menggunakan modul ini.
    1233Fungsi 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 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 yang memiliki status. Di dalam fungsi ini, baris 42 mengatur currentStateName objek ke status yang sedang diatur, baris 4547 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.

  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 di 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 menghidupkan penggeser %s tetapi tidak dapat menemukan Handle", object:GetFullName()))
    end
    local innerFill = object:FindFirstChild("InnerFill", true)
    if not innerFill then
    warn(string.format("Mencoba menghidupkan penggeser %s tetapi tidak dapat menemukan InnerFill", object:GetFullName()))
    end
    local dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
    if not dragDetector then
    warn(string.format("Mencoba menghidupkan penggeser %s tetapi tidak dapat menemukan UIDragDetector", object:GetFullName()))
    end
    local self = setmetatable({
    handle = handle,
    innerFill = innerFill,
    dragDetector = dragDetector,
    value = initialValue or 0.5,
    onChanged = onChanged,
    }, SliderController)
    -- Atur nilai awal
    self:setValue(self.value)
    -- Hubungkan detektor ke 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 frame dalam untuk mencocokkan
    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 memastikan bahwa pegangan, isi dalam, dan elemen UIDragDetector penggeser ada. Baris 38 memanggil fungsi setValue() modul dan baris 4143 menghubungkan acara DragContinue detektor ke fungsi setValue() modul (lihat baris berikutnya untuk detail).
    4861Fungsi yang digunakan untuk mengatur nilai penggeser. Di dalam fungsi ini, baris 5354 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.

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

    Jendela Explorer menunjukkan skrip SettingsScript di dalam wadah HUDContainer.
  2. Tempelkan kode berikut di 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 ke 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 bagian berikut untuk menjelajahi bagaimana skrip memanfaatkan modul kontrol.

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

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

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

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

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

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

    BarisTujuan
    81Menetapkan targetState yang sama untuk SettingsMenu untuk disinkronkan 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 di dalam SoundService. Sebuah SoundGroup memungkinkan Anda mengaitkan beberapa Sounds dan mengontrol volume setiap suara dalam grup melalui properti Volume grup.
    5354Sebuah 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.
    55Nilai awal penggeser diatur ke Volume saat ini dari grup suara Effects, atau 0.5 sebagai cadangan.
    5660Menetapkan fungsi callback untuk menerapkan perubahan nilai penggeser ke volume grup suara Effects.
    6473Pada 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.

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