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

Main Menu Roblox GUI Template with Play / Settings / Store

A polished main menu with animated play button, settings shortcut, store link, and social icons. Features a subtle UIGradient background, smooth Tween animations, and auto-fitting layout that adapts to mobile, tablet, and desktop screens. Fits any genre from simulators to RPGs to obbies.

MenuFree
Main Menu Roblox GUI template — Play / Settings / Store, clean menu layout, screenshot 1
Main Menu Roblox GUI template — screenshot 1 of 1, showing play / settings / store on a clean menu layout for desktop.
Open in Web EditorJoin Studio plugin waitlist

Live preview

Main Menu

1920×1080
Zoom100%
Desktop (FHD)
ScreenGui
Frame
MY GAME
▶ Play
⚙ Settings
🛒 Store
A polished main menu with animated play button, settings shortcut, store link, and social icons. Features a subtle UIGradient background, smooth Tween animations, and auto-fitting layout that adapts to mobile, tablet, and desktop screens. Fits any genre from simulators to RPGs to obbies.

Includes real, production-ready Luau logic — not a static mockup.

What's inside

How to use this template

The Main Menu template is the entry point for any Roblox game. Paste the client Luau into StarterGui and the menu appears with Play, Settings, and Store buttons. The layout uses a centered Frame with UIListLayout, so buttons stack vertically and stay aligned on any screen size. A subtle UIGradient runs across the background for depth. The Play button fires a RemoteEvent to the server to start the match - wire this to your own match-start logic. The Settings and Store buttons open their respective panels, which you can build out or link to your existing UI. The menu uses Scale-based sizing, so it looks right on phone, tablet, and desktop without manual adjustment. To customize, open the template in the editor, recolor the buttons to match your game's theme, and re-export the Luau.

Add it to your game in 3 steps

  1. 1

    Copy the Luau

    Open the template in the web editor and click Export. Choose LocalScript to copy the full client Luau to your clipboard.

  2. 2

    Paste into StarterGui

    In Roblox Studio, right-click StarterGui in the Explorer, insert a LocalScript, and paste the copied Luau. Rename it to match the template.

  3. 3

    Press Play to verify

    Click Play in Studio. The GUI should appear exactly as designed. Tweak any Size or Position values in the script if you want to adjust the layout.

main-menu.lua
lua
1--[[
2 Main Menu System - Client
3 Features: Animated play button, settings, store, social links, auto-fit layout
4 Place in: StarterGui > MainMenuGui
5--]]
6
7local Players = game:GetService("Players")
8local TweenService = game:GetService("TweenService")
9local UserInputService = game:GetService("UserInputService")
10local ReplicatedStorage = game:GetService("ReplicatedStorage")
11local TeleportService = game:GetService("TeleportService")
12local RunService = game:GetService("RunService")
13local MarketplaceService = game:GetService("MarketplaceService")
14
15local player = Players.LocalPlayer
16local playerGui = player:WaitForChild("PlayerGui")
17
18-- ============================================
19-- CONFIGURATION
20-- ============================================
21local CONFIG = {
22 AnimSpeed = 0.35,
23 BounceSpeed = 0.5,
24 GradientSpeed = 0.02,
25 ButtonHoverScale = 1.05,
26 LogoBobSpeed = 2,
27 LogoBobAmount = 8,
28 SocialIds = {
29 Discord = "",
30 Twitter = "",
31 YouTube = "",
32 RobloxGroup = "",
33 },
34 GamepassIds = {},
35 DeveloperProductIds = {},
36}
37
38-- ============================================
39-- UTILITY FUNCTIONS
40-- ============================================
41local function Create(className, properties)
42 local instance = Instance.new(className)
43 for key, value in pairs(properties or {}) do
44 instance[key] = value
45 end
46 return instance
47end
48
49local function Tween(instance, properties, duration, easingStyle, easingDirection)
50 local tween = TweenService:Create(
51 instance,
52 TweenInfo.new(
53 duration or CONFIG.AnimSpeed,
54 easingStyle or Enum.EasingStyle.Quad,
55 easingDirection or Enum.EasingDirection.Out
56 ),
57 properties
58 )
59 tween:Play()
60 return tween
61end
62
63local function TweenBounce(instance, properties, duration)
64 return Tween(instance, properties, duration, Enum.EasingStyle.Back, Enum.EasingDirection.Out)
65end
66
67local function PlaySound(soundId, volume)
68 local sound = Instance.new("Sound")
69 sound.SoundId = soundId
70 sound.Volume = volume or 0.5
71 sound.Parent = playerGui
72 sound:Play()
73 task.delay(sound.TimeLength + 0.5, function()
74 sound:Destroy()
75 end)
76end
77
78-- ============================================
79-- UI CONSTRUCTION
80-- ============================================
81local UI = {}
82
83function UI.Build()
84 -- ScreenGui
85 local screenGui = Create("ScreenGui", {
86 Name = "MainMenuGui",
87 Parent = playerGui,
88 ResetOnSpawn = false,
89 ZIndexBehavior = Enum.ZIndexBehavior.Sibling,
90 IgnoreGuiInset = true,
91 })
92 UI.ScreenGui = screenGui
93
94 -- Background Frame (Full Screen)
95 local bgFrame = Create("Frame", {
96 Name = "BackgroundFrame",
97 Parent = screenGui,
98 Size = UDim2.new(1, 0, 1, 0),
99 BackgroundColor3 = Color3.fromRGB(20, 22, 35),
100 BorderSizePixel = 0,
101 ZIndex = 1,
102 })
103
104 -- Animated Gradient Background
105 local bgGradient = Create("UIGradient", {
106 Color = ColorSequence.new({
107 ColorSequenceKeypoint.new(0, Color3.fromRGB(25, 28, 50)),
108 ColorSequenceKeypoint.new(0.3, Color3.fromRGB(35, 25, 55)),
109 ColorSequenceKeypoint.new(0.6, Color3.fromRGB(25, 35, 55)),
110 ColorSequenceKeypoint.new(1, Color3.fromRGB(20, 30, 45)),
111 }),
112 Rotation = 45,
113 Parent = bgFrame,
114 })
115
116 -- Floating particles (simulated with small frames)
117 UI.Particles = {}
118 for i = 1, 15 do
119 local particle = Create("Frame", {
120 Name = "Particle_" .. i,
121 Parent = bgFrame,
122 Size = UDim2.new(0, math.random(2, 6), 0, math.random(2, 6)),
123 Position = UDim2.new(math.random(), 0, math.random(), 0),
124 BackgroundColor3 = Color3.fromRGB(
125 math.random(100, 200),
126 math.random(120, 220),
127 math.random(180, 255)
128 ),
129 BackgroundTransparency = math.random(40, 70) / 100,
130 BorderSizePixel = 0,
131 ZIndex = 2,
132 })
133 Create("UICorner", {
134 CornerRadius = UDim.new(1, 0),
135 Parent = particle,
136 })
137 table.insert(UI.Particles, {
138 Frame = particle,
139 Speed = math.random(5, 15) / 1000,
140 Direction = math.random() > 0.5 and 1 or -1,
141 })
142 end
143
144 -- Content Frame (Centered)
145 local contentFrame = Create("Frame", {
146 Name = "ContentFrame",
147 Parent = screenGui,
148 AnchorPoint = Vector2.new(0.5, 0.5),
149 Position = UDim2.new(0.5, 0, 0.48, 0),
150 Size = UDim2.new(0, 450, 0, 520),
151 BackgroundTransparency = 1,
152 ZIndex = 10,
153 })
154 UI.ContentFrame = contentFrame
155
156 -- Game Logo
157 UI.GameLogo = Create("ImageLabel", {
158 Name = "GameLogo",
159 Parent = contentFrame,
160 AnchorPoint = Vector2.new(0.5, 0),
161 Position = UDim2.new(0.5, 0, 0, 0),
162 Size = UDim2.new(0, 180, 0, 180),
163 BackgroundTransparency = 1,
164 Image = "rbxassetid://0", -- Replace with your game logo
165 ZIndex = 11,
166 })
167 Create("UICorner", {
168 CornerRadius = UDim.new(0, 20),
169 Parent = UI.GameLogo,
170 })
171 -- Logo glow
172 local logoStroke = Create("UIStroke", {
173 Color = Color3.fromRGB(100, 150, 255),
174 Thickness = 3,
175 Transparency = 0.3,
176 Parent = UI.GameLogo,
177 })
178 UI.LogoStroke = logoStroke
179
180 -- Game Title
181 UI.GameTitle = Create("TextLabel", {
182 Name = "GameTitle",
183 Parent = contentFrame,
184 AnchorPoint = Vector2.new(0.5, 0),
185 Position = UDim2.new(0.5, 0, 0, 190),
186 Size = UDim2.new(1, 0, 0, 50),
187 BackgroundTransparency = 1,
188 Text = "GAME TITLE",
189 TextColor3 = Color3.fromRGB(255, 255, 255),
190 TextSize = 42,
191 Font = Enum.Font.GothamBlack,
192 TextStrokeTransparency = 0.8,
193 TextStrokeColor3 = Color3.fromRGB(50, 100, 200),
194 ZIndex = 11,
195 })
196
197 -- Subtitle
198 UI.Subtitle = Create("TextLabel", {
199 Name = "Subtitle",
200 Parent = contentFrame,
201 AnchorPoint = Vector2.new(0.5, 0),
202 Position = UDim2.new(0.5, 0, 0, 242),
203 Size = UDim2.new(1, 0, 0, 28),
204 BackgroundTransparency = 1,
205 Text = "Your Adventure Begins Here",
206 TextColor3 = Color3.fromRGB(160, 170, 200),
207 TextSize = 18,
208 Font = Enum.Font.GothamSemibold,
209 ZIndex = 11,
210 })
211
212 -- Button Container
213 local buttonContainer = Create("Frame", {
214 Name = "ButtonContainer",
215 Parent = contentFrame,
216 AnchorPoint = Vector2.new(0.5, 0),
217 Position = UDim2.new(0.5, 0, 0, 285),
218 Size = UDim2.new(0, 300, 0, 260),
219 BackgroundTransparency = 1,
220 ZIndex = 11,
221 })
222 Create("UIListLayout", {
223 FillDirection = Enum.FillDirection.Vertical,
224 HorizontalAlignment = Enum.HorizontalAlignment.Center,
225 VerticalAlignment = Enum.VerticalAlignment.Top,
226 Padding = UDim.new(0, 10),
227 Parent = buttonContainer,
228 })
229
230 -- Play Button (Primary - larger, animated)
231 local playButton = Create("TextButton", {
232 Name = "PlayButton",
233 Parent = buttonContainer,
234 Size = UDim2.new(0, 280, 0, 55),
235 BackgroundColor3 = Color3.fromRGB(50, 180, 80),
236 Text = "PLAY",
237 TextColor3 = Color3.fromRGB(255, 255, 255),
238 TextSize = 26,
239 Font = Enum.Font.GothamBlack,
240 ZIndex = 12,
241 })
242 Create("UICorner", {CornerRadius = UDim.new(0, 12), Parent = playButton})
243 local playGradient = Create("UIGradient", {
244 Color = ColorSequence.new({
245 ColorSequenceKeypoint.new(0, Color3.fromRGB(50, 200, 90)),
246 ColorSequenceKeypoint.new(1, Color3.fromRGB(40, 160, 70)),
247 }),
248 Rotation = 90,
249 Parent = playButton,
250 })
251 local playStroke = Create("UIStroke", {
252 Color = Color3.fromRGB(80, 230, 110),
253 Thickness = 2,
254 Transparency = 0.3,
255 Parent = playButton,
256 })
257 UI.PlayButton = playButton
258 UI.PlayGradient = playGradient
259 UI.PlayStroke = playStroke
260
261 -- Store Button
262 local storeButton = Create("TextButton", {
263 Name = "StoreButton",
264 Parent = buttonContainer,
265 Size = UDim2.new(0, 260, 0, 44),
266 BackgroundColor3 = Color3.fromRGB(200, 160, 50),
267 Text = " STORE",
268 TextColor3 = Color3.fromRGB(255, 255, 255),
269 TextSize = 20,
270 Font = Enum.Font.GothamBold,
271 ZIndex = 12,
272 })
273 Create("UICorner", {CornerRadius = UDim.new(0, 10), Parent = storeButton})
274 Create("UIGradient", {
275 Color = ColorSequence.new({
276 ColorSequenceKeypoint.new(0, Color3.fromRGB(220, 175, 55)),
277 ColorSequenceKeypoint.new(1, Color3.fromRGB(180, 140, 45)),
278 }),
279 Rotation = 90,
280 Parent = storeButton,
281 })
282 Create("UIStroke", {
283 Color = Color3.fromRGB(240, 200, 80),
284 Thickness = 1,
285 Transparency = 0.5,
286 Parent = storeButton,
287 })
288 UI.StoreButton = storeButton
289
290 -- Settings Button
291 local settingsButton = Create("TextButton", {
292 Name = "SettingsButton",
293 Parent = buttonContainer,
294 Size = UDim2.new(0, 260, 0, 44),
295 BackgroundColor3 = Color3.fromRGB(80, 90, 130),
296 Text = " SETTINGS",
297 TextColor3 = Color3.fromRGB(255, 255, 255),
298 TextSize = 20,
299 Font = Enum.Font.GothamBold,
300 ZIndex = 12,
301 })
302 Create("UICorner", {CornerRadius = UDim.new(0, 10), Parent = settingsButton})
303 Create("UIGradient", {
304 Color = ColorSequence.new({
305 ColorSequenceKeypoint.new(0, Color3.fromRGB(90, 100, 150)),
306 ColorSequenceKeypoint.new(1, Color3.fromRGB(70, 80, 110)),
307 }),
308 Rotation = 90,
309 Parent = settingsButton,
310 })
311 UI.SettingsButton = settingsButton
312
313 -- Leaderboards Button
314 local leaderboardsButton = Create("TextButton", {
315 Name = "LeaderboardsButton",
316 Parent = buttonContainer,
317 Size = UDim2.new(0, 260, 0, 44),
318 BackgroundColor3 = Color3.fromRGB(130, 70, 150),
319 Text = " LEADERBOARDS",
320 TextColor3 = Color3.fromRGB(255, 255, 255),
321 TextSize = 20,
322 Font = Enum.Font.GothamBold,
323 ZIndex = 12,
324 })
325 Create("UICorner", {CornerRadius = UDim.new(0, 10), Parent = leaderboardsButton})
326 Create("UIGradient", {
327 Color = ColorSequence.new({
328 ColorSequenceKeypoint.new(0, Color3.fromRGB(150, 80, 170)),
329 ColorSequenceKeypoint.new(1, Color3.fromRGB(110, 60, 130)),
330 }),
331 Rotation = 90,
332 Parent = leaderboardsButton,
333 })
334 UI.LeaderboardsButton = leaderboardsButton
335
336 -- Codes Button
337 local codesButton = Create("TextButton", {
338 Name = "CodesButton",
339 Parent = buttonContainer,
340 Size = UDim2.new(0, 260, 0, 44),
341 BackgroundColor3 = Color3.fromRGB(50, 130, 140),
342 Text = " CODES",
343 TextColor3 = Color3.fromRGB(255, 255, 255),
344 TextSize = 20,
345 Font = Enum.Font.GothamBold,
346 ZIndex = 12,
347 })
348 Create("UICorner", {CornerRadius = UDim.new(0, 10), Parent = codesButton})
349 Create("UIGradient", {
350 Color = ColorSequence.new({
351 ColorSequenceKeypoint.new(0, Color3.fromRGB(55, 145, 155)),
352 ColorSequenceKeypoint.new(1, Color3.fromRGB(45, 115, 125)),
353 }),
354 Rotation = 90,
355 Parent = codesButton,
356 })
357 UI.CodesButton = codesButton
358
359 -- Social Container
360 local socialContainer = Create("Frame", {
361 Name = "SocialContainer",
362 Parent = screenGui,
363 AnchorPoint = Vector2.new(0.5, 1),
364 Position = UDim2.new(0.5, 0, 1, -25),
365 Size = UDim2.new(0, 250, 0, 44),
366 BackgroundTransparency = 1,
367 ZIndex = 20,
368 })
369 Create("UIListLayout", {
370 FillDirection = Enum.FillDirection.Horizontal,
371 HorizontalAlignment = Enum.HorizontalAlignment.Center,
372 VerticalAlignment = Enum.VerticalAlignment.Center,
373 Padding = UDim.new(0, 12),
374 Parent = socialContainer,
375 })
376
377 -- Social buttons
378 local socialPlatforms = {
379 {Name = "Discord", Color = Color3.fromRGB(88, 101, 242), Icon = "rbxassetid://0"},
380 {Name = "Twitter", Color = Color3.fromRGB(29, 161, 242), Icon = "rbxassetid://0"},
381 {Name = "YouTube", Color = Color3.fromRGB(255, 0, 0), Icon = "rbxassetid://0"},
382 {Name = "RobloxGroup", Color = Color3.fromRGB(226, 30, 112), Icon = "rbxassetid://0"},
383 }
384 UI.SocialButtons = {}
385 for _, platform in ipairs(socialPlatforms) do
386 local btn = Create("ImageButton", {
387 Name = platform.Name .. "Button",
388 Parent = socialContainer,
389 Size = UDim2.new(0, 40, 0, 40),
390 BackgroundColor3 = platform.Color,
391 Image = platform.Icon,
392 ZIndex = 21,
393 })
394 Create("UICorner", {CornerRadius = UDim.new(0, 10), Parent = btn})
395 UI.SocialButtons[platform.Name] = btn
396 end
397
398 -- Version Label (Bottom right corner)
399 Create("TextLabel", {
400 Name = "VersionLabel",
401 Parent = screenGui,
402 AnchorPoint = Vector2.new(1, 1),
403 Position = UDim2.new(1, -10, 1, -5),
404 Size = UDim2.new(0, 120, 0, 20),
405 BackgroundTransparency = 1,
406 Text = "v1.0.0",
407 TextColor3 = Color3.fromRGB(100, 100, 120),
408 TextSize = 12,
409 Font = Enum.Font.Gotham,
410 TextXAlignment = Enum.TextXAlignment.Right,
411 ZIndex = 20,
412 })
413
414 -- ========== SETTINGS PANEL ==========
415 local settingsPanel = Create("Frame", {
416 Name = "SettingsPanel",
417 Parent = screenGui,
418 AnchorPoint = Vector2.new(0.5, 0.5),
419 Position = UDim2.new(0.5, 0, 0.5, 0),
420 Size = UDim2.new(0, 400, 0, 450),
421 BackgroundColor3 = Color3.fromRGB(30, 32, 48),
422 BorderSizePixel = 0,
423 Visible = false,
424 ZIndex = 100,
425 })
426 UI.SettingsPanel = settingsPanel
427 Create("UICorner", {CornerRadius = UDim.new(0, 16), Parent = settingsPanel})
428 Create("UIStroke", {
429 Color = Color3.fromRGB(80, 85, 120),
430 Thickness = 2,
431 Parent = settingsPanel,
432 })
433
434 -- Settings header
435 local settingsHeader = Create("Frame", {
436 Name = "Header",
437 Parent = settingsPanel,
438 Size = UDim2.new(1, 0, 0, 55),
439 BackgroundColor3 = Color3.fromRGB(38, 40, 58),
440 BorderSizePixel = 0,
441 ZIndex = 101,
442 })
443 Create("UICorner", {CornerRadius = UDim.new(0, 16), Parent = settingsHeader})
444 Create("TextLabel", {
445 Name = "Title",
446 Parent = settingsHeader,
447 Position = UDim2.new(0, 20, 0, 0),
448 Size = UDim2.new(1, -60, 1, 0),
449 BackgroundTransparency = 1,
450 Text = "SETTINGS",
451 TextColor3 = Color3.fromRGB(255, 255, 255),
452 TextSize = 24,
453 Font = Enum.Font.GothamBold,
454 TextXAlignment = Enum.TextXAlignment.Left,
455 ZIndex = 102,
456 })
457 local settingsClose = Create("TextButton", {
458 Name = "CloseButton",
459 Parent = settingsHeader,
460 Position = UDim2.new(1, -45, 0, 10),
461 Size = UDim2.new(0, 35, 0, 35),
462 BackgroundColor3 = Color3.fromRGB(180, 50, 50),
463 Text = "X",
464 TextColor3 = Color3.fromRGB(255, 255, 255),
465 TextSize = 20,
466 Font = Enum.Font.GothamBold,
467 ZIndex = 102,
468 })
469 Create("UICorner", {CornerRadius = UDim.new(0, 8), Parent = settingsClose})
470
471 -- Settings list
472 local settingsList = Create("ScrollingFrame", {
473 Name = "SettingsList",
474 Parent = settingsPanel,
475 Position = UDim2.new(0, 15, 0, 65),
476 Size = UDim2.new(1, -30, 1, -80),
477 BackgroundTransparency = 1,
478 ScrollBarThickness = 6,
479 CanvasSize = UDim2.new(0, 0, 0, 300),
480 ZIndex = 101,
481 })
482 Create("UIListLayout", {
483 Padding = UDim.new(0, 10),
484 Parent = settingsList,
485 })
486
487 -- Create toggle settings
488 local function CreateToggleSetting(name, label, defaultValue)
489 local row = Create("Frame", {
490 Name = name,
491 Parent = settingsList,
492 Size = UDim2.new(1, 0, 0, 50),
493 BackgroundColor3 = Color3.fromRGB(38, 40, 55),
494 BorderSizePixel = 0,
495 ZIndex = 102,
496 })
497 Create("UICorner", {CornerRadius = UDim.new(0, 10), Parent = row})
498 Create("TextLabel", {
499 Parent = row,
500 Position = UDim2.new(0, 15, 0, 0),
501 Size = UDim2.new(0.6, 0, 1, 0),
502 BackgroundTransparency = 1,
503 Text = label,
504 TextColor3 = Color3.fromRGB(220, 220, 240),
505 TextSize = 16,
506 Font = Enum.Font.GothamSemibold,
507 TextXAlignment = Enum.TextXAlignment.Left,
508 ZIndex = 103,
509 })
510 local toggleBtn = Create("TextButton", {
511 Name = "Toggle",
512 Parent = row,
513 Position = UDim2.new(1, -65, 0.5, -15),
514 Size = UDim2.new(0, 50, 0, 30),
515 BackgroundColor3 = defaultValue and Color3.fromRGB(50, 180, 80) or Color3.fromRGB(100, 100, 120),
516 Text = defaultValue and "ON" or "OFF",
517 TextColor3 = Color3.fromRGB(255, 255, 255),
518 TextSize = 14,
519 Font = Enum.Font.GothamBold,
520 ZIndex = 103,
521 })
522 Create("UICorner", {CornerRadius = UDim.new(0, 15), Parent = toggleBtn})
523 return toggleBtn
524 end
525
526 UI.MusicToggle = CreateToggleSetting("MusicToggle", "Background Music", true)
527 UI.SFXToggle = CreateToggleSetting("SFXToggle", "Sound Effects", true)
528
529 -- ========== CODES PANEL ==========
530 local codesPanel = Create("Frame", {
531 Name = "CodesPanel",
532 Parent = screenGui,
533 AnchorPoint = Vector2.new(0.5, 0.5),
534 Position = UDim2.new(0.5, 0, 0.5, 0),
535 Size = UDim2.new(0, 380, 0, 250),
536 BackgroundColor3 = Color3.fromRGB(30, 32, 48),
537 BorderSizePixel = 0,
538 Visible = false,
539 ZIndex = 100,
540 })
541 UI.CodesPanel = codesPanel
542 Create("UICorner", {CornerRadius = UDim.new(0, 16), Parent = codesPanel})
543 Create("UIStroke", {
544 Color = Color3.fromRGB(80, 85, 120),
545 Thickness = 2,
546 Parent = codesPanel,
547 })
548 Create("TextLabel", {
549 Parent = codesPanel,
550 Position = UDim2.new(0, 0, 0, 15),
551 Size = UDim2.new(1, 0, 0, 35),
552 BackgroundTransparency = 1,
553 Text = "REDEEM CODE",
554 TextColor3 = Color3.fromRGB(255, 255, 255),
555 TextSize = 22,
556 Font = Enum.Font.GothamBold,
557 ZIndex = 101,
558 })
559 local codeInput = Create("TextBox", {
560 Name = "CodeInput",
561 Parent = codesPanel,
562 Position = UDim2.new(0.5, -130, 0, 65),
563 Size = UDim2.new(0, 260, 0, 42),
564 BackgroundColor3 = Color3.fromRGB(45, 47, 65),
565 Text = "",
566 PlaceholderText = "Enter code here...",
567 TextColor3 = Color3.fromRGB(255, 255, 255),
568 PlaceholderColor3 = Color3.fromRGB(120, 120, 140),
569 TextSize = 16,
570 Font = Enum.Font.Gotham,
571 ClearTextOnFocus = true,
572 ZIndex = 101,
573 })
574 Create("UICorner", {CornerRadius = UDim.new(0, 10), Parent = codeInput})
575 local redeemBtn = Create("TextButton", {
576 Name = "RedeemButton",
577 Parent = codesPanel,
578 Position = UDim2.new(0.5, -80, 0, 125),
579 Size = UDim2.new(0, 160, 0, 42),
580 BackgroundColor3 = Color3.fromRGB(50, 180, 80),
581 Text = "REDEEM",
582 TextColor3 = Color3.fromRGB(255, 255, 255),
583 TextSize = 18,
584 Font = Enum.Font.GothamBold,
585 ZIndex = 101,
586 })
587 Create("UICorner", {CornerRadius = UDim.new(0, 10), Parent = redeemBtn})
588 UI.RedeemButton = redeemBtn
589 UI.CodeInput = codeInput
590 local codeClose = Create("TextButton", {
591 Name = "CloseButton",
592 Parent = codesPanel,
593 Position = UDim2.new(1, -45, 0, 10),
594 Size = UDim2.new(0, 35, 0, 35),
595 BackgroundColor3 = Color3.fromRGB(180, 50, 50),
596 Text = "X",
597 TextColor3 = Color3.fromRGB(255, 255, 255),
598 TextSize = 20,
599 Font = Enum.Font.GothamBold,
600 ZIndex = 101,
601 })
602 Create("UICorner", {CornerRadius = UDim.new(0, 8), Parent = codeClose})
603
604 -- ========== LOADING OVERLAY ==========
605 local loadingOverlay = Create("Frame", {
606 Name = "LoadingOverlay",
607 Parent = screenGui,
608 Size = UDim2.new(1, 0, 1, 0),
609 BackgroundColor3 = Color3.fromRGB(15, 15, 25),
610 BorderSizePixel = 0,
611 Visible = false,
612 ZIndex = 500,
613 })
614 UI.LoadingOverlay = loadingOverlay
615 Create("TextLabel", {
616 Name = "LoadingText",
617 Parent = loadingOverlay,
618 AnchorPoint = Vector2.new(0.5, 0.5),
619 Position = UDim2.new(0.5, 0, 0.42, 0),
620 Size = UDim2.new(0, 300, 0, 40),
621 BackgroundTransparency = 1,
622 Text = "Loading...",
623 TextColor3 = Color3.fromRGB(255, 255, 255),
624 TextSize = 28,
625 Font = Enum.Font.GothamBold,
626 ZIndex = 501,
627 })
628 local loadingBarBg = Create("Frame", {
629 Name = "LoadingBarBg",
630 Parent = loadingOverlay,
631 AnchorPoint = Vector2.new(0.5, 0.5),
632 Position = UDim2.new(0.5, 0, 0.52, 0),
633 Size = UDim2.new(0, 300, 0, 12),
634 BackgroundColor3 = Color3.fromRGB(40, 40, 60),
635 BorderSizePixel = 0,
636 ZIndex = 501,
637 })
638 Create("UICorner", {CornerRadius = UDim.new(0, 6), Parent = loadingBarBg})
639 UI.LoadingBar = Create("Frame", {
640 Name = "LoadingBar",
641 Parent = loadingBarBg,
642 Size = UDim2.new(0, 0, 1, 0),
643 BackgroundColor3 = Color3.fromRGB(50, 180, 80),
644 BorderSizePixel = 0,
645 ZIndex = 502,
646 })
647 Create("UICorner", {CornerRadius = UDim.new(0, 6), Parent = UI.LoadingBar})
648
649 return UI
650end
651
652-- ============================================
653-- ANIMATIONS & EFFECTS
654-- ============================================
655function UI.SetupAnimations()
656 -- Background gradient animation (rotates slowly)
657 local gradientRotation = 45
658 task.spawn(function()
659 while UI.ScreenGui and UI.ScreenGui.Parent do
660 gradientRotation = gradientRotation + CONFIG.GradientSpeed * 360 * task.wait(0.05)
661 local bgGradient = UI.ScreenGui.BackgroundFrame:FindFirstChildOfClass("UIGradient")
662 if bgGradient then
663 bgGradient.Rotation = gradientRotation
664 end
665 end
666 end)
667
668 -- Floating particles animation
669 task.spawn(function()
670 while UI.ScreenGui and UI.ScreenGui.Parent do
671 for _, p in ipairs(UI.Particles) do
672 local currentPos = p.Frame.Position
673 local newX = currentPos.X.Scale + p.Speed * p.Direction
674 local newY = currentPos.Y.Scale - p.Speed * 0.3
675
676 -- Wrap around
677 if newX > 1 then newX = -0.05 end
678 if newX < -0.05 then newX = 1 end
679 if newY < -0.05 then newY = 1 end
680
681 p.Frame.Position = UDim2.new(newX, 0, newY, 0)
682 end
683 task.wait(0.05)
684 end
685 end)
686
687 -- Logo bobbing animation
688 task.spawn(function()
689 local startTime = tick()
690 while UI.ScreenGui and UI.ScreenGui.Parent do
691 local elapsed = tick() - startTime
692 local offset = math.sin(elapsed * CONFIG.LogoBobSpeed) * CONFIG.LogoBobAmount
693 UI.GameLogo.Position = UDim2.new(0.5, 0, 0, offset)
694
695 -- Pulsing glow
696 local pulse = 0.3 + math.sin(elapsed * 1.5) * 0.2
697 UI.LogoStroke.Transparency = pulse
698
699 task.wait(0.05)
700 end
701 end)
702
703 -- Play button pulse animation
704 task.spawn(function()
705 local startTime = tick()
706 while UI.ScreenGui and UI.ScreenGui.Parent do
707 local elapsed = tick() - startTime
708 local pulse = 1 + math.sin(elapsed * 2) * 0.02
709 if not State.PlayButtonHovered then
710 UI.PlayButton.Size = UDim2.new(0, 280 * pulse, 0, 55 * pulse)
711 end
712 task.wait(0.05)
713 end
714 end)
715
716 -- Button hover effects
717 local buttons = {
718 {Btn = UI.PlayButton, OriginalSize = UDim2.new(0, 280, 0, 55)},
719 {Btn = UI.StoreButton, OriginalSize = UDim2.new(0, 260, 0, 44)},
720 {Btn = UI.SettingsButton, OriginalSize = UDim2.new(0, 260, 0, 44)},
721 {Btn = UI.LeaderboardsButton, OriginalSize = UDim2.new(0, 260, 0, 44)},
722 {Btn = UI.CodesButton, OriginalSize = UDim2.new(0, 260, 0, 44)},
723 }
724
725 for _, btnData in ipairs(buttons) do
726 btnData.Btn.MouseEnter:Connect(function()
727 Tween(btnData.Btn, {Size = UDim2.new(
728 0, btnData.OriginalSize.X.Offset * CONFIG.ButtonHoverScale,
729 0, btnData.OriginalSize.Y.Offset * CONFIG.ButtonHoverScale
730 )}, 0.15)
731 if btnData.Btn == UI.PlayButton then
732 State.PlayButtonHovered = true
733 Tween(UI.PlayStroke, {Transparency = 0}, 0.15)
734 end
735 end)
736
737 btnData.Btn.MouseLeave:Connect(function()
738 Tween(btnData.Btn, {Size = btnData.OriginalSize}, 0.15)
739 if btnData.Btn == UI.PlayButton then
740 State.PlayButtonHovered = false
741 Tween(UI.PlayStroke, {Transparency = 0.3}, 0.15)
742 end
743 end)
744 end
745
746 -- Social button hover
747 for name, btn in pairs(UI.SocialButtons) do
748 btn.MouseEnter:Connect(function()
749 Tween(btn, {Size = UDim2.new(0, 46, 0, 46)}, 0.15)
750 end)
751 btn.MouseLeave:Connect(function()
752 Tween(btn, {Size = UDim2.new(0, 40, 0, 40)}, 0.15)
753 end)
754 end
755end
756
757-- ============================================
758-- INTERACTION LOGIC
759-- ============================================
760local State = {
761 PlayButtonHovered = false,
762 MenuVisible = true,
763 SettingsOpen = false,
764 CodesOpen = false,
765 MusicEnabled = true,
766 SFXEnabled = true,
767}
768
769local Logic = {}
770
771function Logic.SetupInteractions()
772 -- Play Button - Start Game
773 UI.PlayButton.MouseButton1Click:Connect(function()
774 Logic.StartGame()
775 end)
776
777 -- Store Button - Open Store
778 UI.StoreButton.MouseButton1Click:Connect(function()
779 Logic.OpenStore()
780 end)
781
782 -- Settings Button - Toggle Settings Panel
783 UI.SettingsButton.MouseButton1Click:Connect(function()
784 Logic.ToggleSettings()
785 end)
786
787 -- Settings Close Button
788 UI.SettingsPanel.Header.CloseButton.MouseButton1Click:Connect(function()
789 Logic.HideSettings()
790 end)
791
792 -- Leaderboards Button
793 UI.LeaderboardsButton.MouseButton1Click:Connect(function()
794 Logic.OpenLeaderboards()
795 end)
796
797 -- Codes Button - Toggle Codes Panel
798 UI.CodesButton.MouseButton1Click:Connect(function()
799 Logic.ToggleCodes()
800 end)
801
802 -- Codes Close Button
803 UI.CodesPanel.CloseButton.MouseButton1Click:Connect(function()
804 Logic.HideCodes()
805 end)
806
807 -- Redeem Button
808 UI.RedeemButton.MouseButton1Click:Connect(function()
809 Logic.RedeemCode(UI.CodeInput.Text)
810 end)
811
812 -- Music Toggle
813 UI.MusicToggle.MouseButton1Click:Connect(function()
814 State.MusicEnabled = not State.MusicEnabled
815 UI.MusicToggle.BackgroundColor3 = State.MusicEnabled
816 and Color3.fromRGB(50, 180, 80) or Color3.fromRGB(100, 100, 120)
817 UI.MusicToggle.Text = State.MusicEnabled and "ON" or "OFF"
818 -- Apply to SoundService
819 -- SoundService.[music].Playing = State.MusicEnabled
820 end)
821
822 -- SFX Toggle
823 UI.SFXToggle.MouseButton1Click:Connect(function()
824 State.SFXEnabled = not State.SFXEnabled
825 UI.SFXToggle.BackgroundColor3 = State.SFXEnabled
826 and Color3.fromRGB(50, 180, 80) or Color3.fromRGB(100, 100, 120)
827 UI.SFXToggle.Text = State.SFXEnabled and "ON" or "OFF"
828 end)
829
830 -- Social Buttons
831 UI.SocialButtons.Discord.MouseButton1Click:Connect(function()
832 -- Copy invite to clipboard
833 -- setclipboard(CONFIG.SocialIds.Discord)
834 print("Discord invite copied!")
835 end)
836 UI.SocialButtons.Twitter.MouseButton1Click:Connect(function()
837 -- setclipboard(CONFIG.SocialIds.Twitter)
838 print("Twitter link copied!")
839 end)
840 UI.SocialButtons.YouTube.MouseButton1Click:Connect(function()
841 -- setclipboard(CONFIG.SocialIds.YouTube)
842 print("YouTube link copied!")
843 end)
844 UI.SocialButtons.RobloxGroup.MouseButton1Click:Connect(function()
845 -- setclipboard(CONFIG.SocialIds.RobloxGroup)
846 print("Roblox Group link copied!")
847 end)
848end
849
850function Logic.StartGame()
851 -- Animate loading overlay
852 UI.LoadingOverlay.Visible = true
853 UI.LoadingBar.Size = UDim2.new(0, 0, 1, 0)
854
855 -- Simulate loading steps
856 local steps = {0.1, 0.25, 0.45, 0.7, 0.85, 1.0}
857 for _, progress in ipairs(steps) do
858 Tween(UI.LoadingBar, {Size = UDim2.new(progress, 0, 1, 0)}, 0.3)
859 task.wait(0.4)
860 end
861
862 task.wait(0.3)
863
864 -- Hide main menu and loading
865 UI.ScreenGui.Enabled = false
866 UI.LoadingOverlay.Visible = false
867
868 -- Fire remote to spawn player
869 local spawnRemote = ReplicatedStorage:FindFirstChild("SpawnPlayer")
870 if spawnRemote then
871 spawnRemote:FireServer()
872 end
873
874 -- Alternatively, teleport to game place
875 -- TeleportService:Teleport(gamePlaceId, player)
876
877 print("Game started!")
878end
879
880function Logic.OpenStore()
881 -- Open the Store GUI (from Shop UI template)
882 print("Opening store...")
883 -- Fire event to show Store UI
884 local showStore = ReplicatedStorage:FindFirstChild("ShowStore")
885 if showStore then
886 showStore:Fire()
887 end
888end
889
890function Logic.ToggleSettings()
891 if State.SettingsOpen then
892 Logic.HideSettings()
893 else
894 Logic.ShowSettings()
895 end
896end
897
898function Logic.ShowSettings()
899 State.SettingsOpen = true
900 UI.SettingsPanel.Visible = true
901 UI.SettingsPanel.Size = UDim2.new(0, 350, 0, 400)
902 TweenBounce(UI.SettingsPanel, {Size = UDim2.new(0, 400, 0, 450)}, 0.3)
903end
904
905function Logic.HideSettings()
906 State.SettingsOpen = false
907 Tween(UI.SettingsPanel, {Size = UDim2.new(0, 350, 0, 400)}, 0.2)
908 task.delay(0.2, function()
909 UI.SettingsPanel.Visible = false
910 end)
911end
912
913function Logic.OpenLeaderboards()
914 print("Opening leaderboards...")
915 -- Trigger leaderboards UI
916end
917
918function Logic.ToggleCodes()
919 if State.CodesOpen then
920 Logic.HideCodes()
921 else
922 Logic.ShowCodes()
923 end
924end
925
926function Logic.ShowCodes()
927 State.CodesOpen = true
928 UI.CodesPanel.Visible = true
929 UI.CodesPanel.Size = UDim2.new(0, 340, 0, 220)
930 TweenBounce(UI.CodesPanel, {Size = UDim2.new(0, 380, 0, 250)}, 0.3)
931end
932
933function Logic.HideCodes()
934 State.CodesOpen = false
935 Tween(UI.CodesPanel, {Size = UDim2.new(0, 340, 0, 220)}, 0.2)
936 task.delay(0.2, function()
937 UI.CodesPanel.Visible = false
938 end)
939end
940
941function Logic.RedeemCode(code)
942 if code == "" or code == "Enter code here..." then
943 return
944 end
945
946 UI.RedeemButton.Text = "Checking..."
947 UI.RedeemButton.BackgroundColor3 = Color3.fromRGB(100, 100, 120)
948
949 -- Fire remote to validate code
950 local validateCode = ReplicatedStorage:FindFirstChild("ValidateCode")
951 if validateCode then
952 local result = validateCode:InvokeServer(code)
953 if result.Success then
954 UI.RedeemButton.Text = "Success!"
955 UI.RedeemButton.BackgroundColor3 = Color3.fromRGB(50, 180, 80)
956 UI.CodeInput.Text = ""
957 task.delay(1.5, function()
958 UI.RedeemButton.Text = "REDEEM"
959 UI.RedeemButton.BackgroundColor3 = Color3.fromRGB(50, 180, 80)
960 end)
961 else
962 UI.RedeemButton.Text = result.Message or "Invalid Code"
963 UI.RedeemButton.BackgroundColor3 = Color3.fromRGB(180, 50, 50)
964 task.delay(2, function()
965 UI.RedeemButton.Text = "REDEEM"
966 UI.RedeemButton.BackgroundColor3 = Color3.fromRGB(50, 180, 80)
967 end)
968 end
969 else
970 UI.RedeemButton.Text = "Server Error"
971 task.delay(2, function()
972 UI.RedeemButton.Text = "REDEEM"
973 UI.RedeemButton.BackgroundColor3 = Color3.fromRGB(50, 180, 80)
974 end)
975 end
976end
977
978-- ============================================
979-- RESPONSIVE LAYOUT
980-- ============================================
981function Logic.SetupResponsive()
982 local function UpdateLayout()
983 local viewportSize = workspace.CurrentCamera.ViewportSize
984 local isMobile = viewportSize.X < 600
985 local isTablet = viewportSize.X >= 600 and viewportSize.X < 1024
986
987 if isMobile then
988 -- Mobile layout
989 UI.ContentFrame.Size = UDim2.new(0.9, 0, 0.85, 0)
990 UI.ContentFrame.Position = UDim2.new(0.5, 0, 0.5, 0)
991 UI.GameLogo.Size = UDim2.new(0, 120, 0, 120)
992 UI.GameTitle.TextSize = 28
993 UI.GameTitle.Position = UDim2.new(0.5, 0, 0, 130)
994 UI.Subtitle.TextSize = 14
995 UI.Subtitle.Position = UDim2.new(0.5, 0, 0, 168)
996 UI.PlayButton.Size = UDim2.new(0, 240, 0, 50)
997 UI.StoreButton.Size = UDim2.new(0, 220, 0, 40)
998 UI.SettingsButton.Size = UDim2.new(0, 220, 0, 40)
999 elseif isTablet then
1000 -- Tablet layout
1001 UI.ContentFrame.Size = UDim2.new(0, 420, 0, 500)
1002 UI.ContentFrame.Position = UDim2.new(0.5, 0, 0.48, 0)
1003 UI.GameLogo.Size = UDim2.new(0, 150, 0, 150)
1004 UI.GameTitle.TextSize = 36
1005 UI.GameTitle.Position = UDim2.new(0.5, 0, 0, 160)
1006 UI.Subtitle.TextSize = 16
1007 UI.Subtitle.Position = UDim2.new(0.5, 0, 0, 208)
1008 else
1009 -- Desktop layout (default)
1010 UI.ContentFrame.Size = UDim2.new(0, 450, 0, 520)
1011 UI.ContentFrame.Position = UDim2.new(0.5, 0, 0.48, 0)
1012 UI.GameLogo.Size = UDim2.new(0, 180, 0, 180)
1013 UI.GameTitle.TextSize = 42
1014 UI.GameTitle.Position = UDim2.new(0.5, 0, 0, 190)
1015 UI.Subtitle.TextSize = 18
1016 UI.Subtitle.Position = UDim2.new(0.5, 0, 0, 242)
1017 end
1018 end
1019
1020 workspace.CurrentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(UpdateLayout)
1021 UpdateLayout()
1022end
1023
1024-- ============================================
1025-- INITIALIZATION
1026-- ============================================
1027UI.Build()
1028UI.SetupAnimations()
1029UI.SetupInteractions()
1030Logic.SetupResponsive()
1031
1032-- Keep player character from spawning until Play is clicked
1033local function onCharacterAdded(character)
1034 -- Wait for humanoid and anchor
1035 local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
1036 humanoidRootPart.Anchored = true
1037 local humanoid = character:WaitForChild("Humanoid")
1038 humanoid.WalkSpeed = 0
1039 humanoid.JumpPower = 0
1040end
1041
1042if player.Character then
1043 onCharacterAdded(player.Character)
1044end
1045player.CharacterAdded:Connect(onCharacterAdded)
1046
1047print("Main Menu initialized successfully!")

Code preview

Main Menu

Luau
Interactive visual preview is shown in the Live preview section above.Switch tabs to inspect the generated Luau client/server code.
Visual preview of the templateRoblox GUI Maker

Frequently asked questions

Keep going

Similar templates