Roblox GUI Maker logoRoblox GUI Maker
Unofficial third-party tool · Not affiliated with Roblox Corporation

Roblox Settings Menu Template: Volume, Graphics, Keybinds (2026)

2026-07-21 · Roblox GUI Maker Team

Settings menu structure with UIListLayout

Build the settings menu as a single Frame with a UIListLayout inside. Each row is a setting: a label on the left and a control (slider or toggle) on the right. UIListLayout stacks the rows automatically with consistent spacing, so adding a new setting is one Frame. The menu opens from a gear button in the corner and closes with Escape or a close button. Use Scale-based sizing so the menu fits any screen, and put a semi-transparent backdrop behind it that closes the menu when clicked.

Volume sliders with live SoundService binding

The volume slider is a draggable handle on a track. When the player drags it, update SoundService.AudioEffects or your custom audio groups immediately - no server round-trip needed. The slider value is a ratio (0 to 1) that maps to volume (0 to 100%). Show the current value as a percentage next to the slider. Save the value to a settings table so it can be persisted to DataStore on change or on leave.

StarterGui/SettingsClient (LocalScript)
lua
1-- Settings Menu - Client Script
2-- Place in: StarterGui (LocalScript)
3
4local Players = game:GetService("Players")
5local SoundService = game:GetService("SoundService")
6local ReplicatedStorage = game:GetService("ReplicatedStorage")
7
8local player = Players.LocalPlayer
9local gui = script.Parent
10local settings = { masterVolume = 0.5, musicOn = true, quality = "Auto" }
11
12local saveEvent = ReplicatedStorage:WaitForChild("SaveSettings")
13
14-- Volume slider: bind to SoundService live
15local volumeSlider = gui:WaitForChild("VolumeSlider")
16local volumeHandle = volumeSlider:WaitForChild("Handle")
17local volumeLabel = volumeSlider:WaitForChild("ValueLabel")
18
19local function setVolume(ratio)
20 settings.masterVolume = ratio
21 SoundService.Volume = ratio
22 volumeLabel.Text = math.floor(ratio * 100) .. "%"
23 volumeHandle.Position = UDim2.new(ratio, 0, 0.5, 0)
24 saveEvent:FireServer(settings)
25end
26
27-- Drag the handle
28local dragging = false
29volumeHandle.MouseButton1Down:Connect(function() dragging = true end)
30game:GetService("UserInputService").InputEnded:Connect(function()
31 if dragging then dragging = false end
32end)
33volumeSlider.MouseMoved:Connect(function(x)
34 if dragging then
35 local rel = math.clamp((x - volumeSlider.AbsolutePosition.X) / volumeSlider.AbsoluteSize.X, 0, 1)
36 setVolume(rel)
37 end
38end)

Graphics and quality toggles

Graphics settings let players trade visual quality for performance. A quality dropdown (Auto/Low/Medium/High) maps to GraphicsQualityLevel in GameSettings, or to your own lighting and shadow toggles if you manage them manually. Show the current quality as the dropdown label, and apply it immediately on change. On mobile, default to Auto or Low so the game runs smoothly on lower-end devices.

Keybind settings

Keybinds let players remap actions to their preferred keys. Store keybinds as a table mapping action names to KeyCode strings, and show each as a row with the action name and its current key. When the player clicks a key row, wait for the next key press and assign it. Save keybinds to DataStore with the rest of the settings. Common keybinds include inventory toggle, sprint, jump, and menu open.

Save settings with DataStore

Settings mean nothing if they reset on rejoin. Save the settings table to DataStore whenever the player changes a value, and load it on join to restore their preferences. Wrap DataStore calls in pcall so a failed save does not crash the game, and save on PlayerRemoving as a final backup. On join, apply the loaded values to every slider, toggle, and keybind row so the menu shows the player's saved state.

ServerScriptService/SettingsServer (Script)
lua
1-- Settings Menu - Server Script
2-- Place in: ServerScriptService (Script)
3
4local Players = game:GetService("Players")
5local DataStoreService = game:GetService("DataStoreService")
6local ReplicatedStorage = game:GetService("ReplicatedStorage")
7
8local settingsStore = DataStoreService:GetDataStore("PlayerSettings")
9local saveEvent = ReplicatedStorage:WaitForChild("SaveSettings")
10local loadEvent = ReplicatedStorage:WaitForChild("LoadSettings")
11
12local playerSettings = {}
13
14-- Load settings on join
15local function loadSettings(player)
16 local success, data = pcall(function()
17 return settingsStore:GetAsync(player.UserId)
18 end)
19 playerSettings[player.UserId] = (success and data) or {}
20 loadEvent:FireClient(player, playerSettings[player.UserId])
21end
22
23-- Save settings
24saveEvent.OnServerEvent:Connect(function(player, settings)
25 playerSettings[player.UserId] = settings
26 pcall(function()
27 settingsStore:SetAsync(player.UserId, settings)
28 end)
29end)
30
31Players.PlayerAdded:Connect(loadSettings)
32Players.PlayerRemoving:Connect(function(player)
33 if playerSettings[player.UserId] then
34 pcall(function()
35 settingsStore:SetAsync(player.UserId, playerSettings[player.UserId])
36 end)
37 end
38end)

Frequently asked questions