Advanced Main Menu with cool scenery! - Tutorial


Oi! I’m Jack, also known as LittleJackBlocks! This is actually my first tutorial, and I will be teaching you how to make a custom main menu screen with a cool scene. This is something I find myself and other users making for their game, so I thought I’d make a tutorial on it, without further ado, let’s get started!

Scene and lighting

First of all, let’s make a scene for this! We need to make a rather simple, small and comfy looking place to add our camera in. If you have a scene already, this is not a necessary step for you. I made a small island like build, not too many details, make sure not to add unnecessary parts all over the place, choose where you want your camera to be and what the player should see.

My scene


Now let’s continue with some better lightning settings, you can fully customize them yourself! In my case, I need it to look slightly bright, the campfire needs a slight glow, and I want the scene to be in the afternoon, so I chose these settings! Keep in mind, the lightning is optional

Lighting settings


After you’re done with the lighting settings, let’s get to some other lighting options!

Let’s add some blur, the amount of blur I want in my scene is quite strong, just enough to give it that dreamy effect. The amount I’ll use is 10.

Blur amount


Now I’ll add some bloom to make the fire from the campfire stand out, the amount of intensity I used is 3, everything else is default.


To customize this even more, I’ll add Color correction!

Color Correction

UI design and scripting

To start off, we need to make a simple GUI, I’ll make a few buttons right now. (Make sure to have GUIInset enabled!

Designing the UI

First, we need to create a ‘ScreenGUI!’ Make sure to name it. Then, insert a few TextButton 's inside of your ScreenGUI. Rename the TextButton and customize it however you want to, make sure to remove the ‘Offset’ from the Size property and to add ‘Scale’ instead so players on every device can see it the same Size. Make sure to have TextScaled Enabled! I used a UIGradient and a new font. Here’s a screenshot!


Now, let’s get to the scripting of the UI! This should be rather simple. Let’s start off by inserting a LocalScript inside of the UI’s Parent. I’ll name it “MainMenuHandler”. Then, insert a Part into Workspace and name it something, I’ll name it “CameraPart,” make sure that the front of the part is facing your scene. Make sure that it’s anchored and can collide is off.



Our Variables

Our variables

First of all, let’s create our variables! You can freely customize your variables and name them whatever you want to!

-- Variables

local Player = game.Players.LocalPlayer -- This indicates what the "Player" variable is.
local Character = Player.Character -- This indicates what the "Character" variable is
local Camera = workspace.CurrentCamera -- This what the "Camera" variable is and what it means
local Mouse = game.Players.LocalPlayer:GetMouse() -- Getting the mouse
local DefaultCFrame = workspace.CameraPart.CFrame -- This variable is our part's position
local Scale = 500
local Background = script.Parent -- We indicate what the "Background" variable means and what it is.
local PlayButton = Background.PlayButton -- Now we do the same with the other variables.
local CreditsButton = Background.CreditsButton 
local StoreButton = Background.StoreButton 
local TweenService = game:GetService("TweenService") -- Calling the service known as "TweenService"

All of these buttons are in the UI, so make sure you did the previous steps before doing this one.

Lock Character and Camera

Since the variables can’t create the code themselves, we have to create it ourselves! First, let’s start off with the camera. You’re free to adjust this code however you’d like to. First of all, let’s a LocalScript inside of StarterCharacterScripts, name them however you want to. This is a script that makes sure the character’s HumanoidRootPart is anchored, this is so the player cannot move. Meaning, they can’t fall off the map, also make sure to add a SpawnLocation and make sure it’s transparent or at least hidden.

script.Parent:WaitForChild("HumanoidRootPart").Anchored = true


Now, let’s do the camera script, I want my camera to slightly pan whenever the cursor moves, I also want it to face the scene. Feel free to customize the script.

Camera script
-- Scripting the Camera

repeat wait() -- - We made the loop so the camera will be set to the Scriptable property.
	Camera.CameraType = Enum.CameraType.Scriptable -- The line of code in which we tell the game that we need the camera to be set to the Scriptable property.
until Camera.CameraType == Enum.CameraType.Scriptable -- And this line is telling the game that if the Camera is set to the Scriptable property, then the loop ends.

game:GetService("RunService").RenderStepped:Connect(function() -- Getting the service known as "RunService"
	Camera.Focus = DefaultCFrame
	local Center =, Camera.ViewportSize.Y/2)
	local MoveVector =, -(Mouse.Y-Center.Y)/Scale, 0)
	Camera.CFrame = DefaultCFrame * CFrame.Angles(math.rad(MoveVector.X), math.rad(MoveVector.Y), math.rad(MoveVector.Z))
	Camera.FieldOfView = 83 -- Setting the FieldOfView, you're free to customize this however you want to

Camera.CFrame = workspace.CameraPart.CFrame -- This is where your camera is, and the "CameraPart" is what my part is called.

After we’re done with the camera, we have to do the UI, this should be quite simple, and feel free to customize it!

Scripting the GUI!

GUI Script
-- Scripting the UI

local function Hover(HoverEffect) -- Make function for it to move a bit.
	local originalPosition = HoverEffect.Position
		PlayButton.TextColor3 =, 1, 0.498039) -- Adding a color whenever the player hovers over the UI
		StoreButton.TextColor3 =, 1, 0.498039)
		CreditsButton.TextColor3 =, 1, 0.498039)
		HoverEffect:TweenPosition((originalPosition +, 0, 0, 0)), "Out", "Sine", .1, true) -- The code that makes the mouse move
		PlayButton.TextColor3 =, 0.243137, 0.243137) -- Adding a color whenever the player stops hovering over the UI
		StoreButton.TextColor3 =, 0.243137, 0.243137)
		CreditsButton.TextColor3 =, 0.243137, 0.243137)
		HoverEffect:TweenPosition((originalPosition), "Out", "Sine", .1, true)

-- This part of the code helps trigger the UI to move

Final product:


All of the code should be self explanatory, I even added some text in the code as a way for you to learn what the code does, I’ll also add a link to the place since I’ll add more overtime, feel free to code the rest of the buttons so they’re functional, I’ll also make some myself. I accept any type of criticism, as this is my first time and I’d like to improve, thanks for reading, have an amazing rest of your day/night!


Pretty cool. I like the feature that, the camera moves a bit if you move your mouse. How does it happen in mobile tho? And if there is anything to improve here, you should improve the GUI a bit.


Ah, I’m not sure how it will work on mobile as I haven’t really planned on making this for mobile, but I might make a mobile edition of this tutorial. Oh, and the UI was quite rushed, I would’ve made it better if it were an actual project. Anyway, thanks for the feedback, hope you have an amazing rest of your day/night! :smiley:


Looks great. You need to tick the IgnoreGuInset option of the ScreenGui, however, or you’ll end up with the 36 pixel at the top of the screen, like in your screenshot, where you’re missing the white gradient background.


you need to scale the background UI more than {1.0,1.0}, because the top didn’t filled… Try to make it bigger and drag the UI on the top


mm is very good in my opinion I wanted very well with a horror game :thinking:


Very nice idea for a menu, explained really nicely, well done!


I realise this is a very late reply, but I have set up a system that when the “Play” button is pressed the GUI is removed and the player respawned - but how do I make it so that it reverts back to the player’s view instead of camera view?

1 Like

Well, I usually have a separate place, and when the player presses the “Play” button, they get teleported to the main place. This can be achieved by using TeleportService.


This also prevents lag.

1 Like

If I was to keep the player in the same place, is there a way I can revert the view back to the player’s view and respawn them? I’m not really worrying about lag as of now.

1 Like

You could just remove this line, I suppose. If you also wanna remove the UI, just disable it, make sure ResetOnSpawn is off.

1 Like

I tried removing the line, for some reason nothing happened - the view is still locked onto the camera.

1 Like

You’re pretty much just making this harder for yourself, creating a new place and using a new place would be easier and would reduce lag, if your game happens to have a lot of parts or lighting, you would just make it harder for yourself to transfer scripts and stuff…

1 Like

Hey, I love this tutorial but am confused on where the scripts go. Do the variables go under each UI element? I’m not new to scripting, but I am really, really bad.



This is also a late reply but I really need to know how to do this as I’m not sure how to pass information such as the team that has been selected in the main menu into a new place.

1 Like

the other guy probably doesn’t know how and is most likely just avoiding the question, what you can do is this (it worked for me):

first, for the RunService code replace it with this

local UpdateCam = game:GetService("RunService").RenderStepped:Connect(function() -- We make it a variable so we can reference it in the same script and disconnect it (disable it/destroy it)
	Camera.Focus = DefaultCFrame
	local Center =, Camera.ViewportSize.Y/2)
	local MoveVector =, -(Mouse.Y-Center.Y)/Scale, 0)
	Camera.CFrame = DefaultCFrame * CFrame.Angles(math.rad(MoveVector.X), math.rad(MoveVector.Y), math.rad(MoveVector.Z))
	Camera.FieldOfView = 83

then on the play button code add this:

Camera.CameraType = Enum.CameraType.Custom -- Sets the Camera to Custom
UpdateCam:Disconnect() -- Destroys/disables the RenderStepped
Camera.CameraSubject = Player.Character:WaitForChild("Humanoid") -- Sets the subject of the camera back to the Player

if this didn’t work please send me your code


Thank you so much, I’ll try it and let you know how it goes.

EDIT: Works Perfectly, Thank you so much for your help.