Build a Game Main Menu with Unity

Design and wire up a styled game menu using Unity's UI Toolkit.

Introduction

30 Second Summary

Every game you've ever played starts with the same screen. A title, a few buttons, and a settings menu that sets the tone before a single frame of gameplay loads.

In this project, you will build a fully styled, interactive game main menu using Unity's modern UI Toolkit system. You'll create a dark-themed title screen with clickable buttons, a settings panel, and C# scripting that wires everything together.

What You'll Build

When you hit Play in the Unity Editor, a polished dark-themed title screen appears with a glowing game title and three interactive buttons that navigate between screens on click.

By the end of this project, you'll have:

  • A dark-themed title screen where you click Play, Settings, or Quit and each button responds with a visible action in the Console or on screen.
  • A settings panel with a volume slider and fullscreen toggle that swaps in when you click Settings and disappears when you click Back.
  • A USS stylesheet that controls all the visual styling (colors, spacing, rounded corners, layout) across your entire menu.
  • Secret Mission: Add animated hover transitions so buttons scale up and change color when your mouse hovers over them.

Are there any prerequisites?

You need Unity 6.3 LTS installed on your computer. All other tools (UI Builder, the script editor) are built into Unity. No additional downloads required.

Before We Start

Before We Start...

Before we dive in, let's lock in what you're about to build and why it matters.

You're going to create a fully styled, interactive game main menu from scratch using Unity's modern UI Toolkit system. Take a moment to commit to this goal before any hands-on work begins.

Set Up a New Unity Project

Every game menu needs a foundation before you can build buttons or style text. You need a clean Unity project with a connected UI canvas in the scene.

A UIDocument is what links your scene to Unity's UI Toolkit system. In this step, you'll create a fresh project, add a UIDocument, and confirm the wiring works by entering Play mode.

In this step, get ready to:
  • Create a new Unity 2D project named GameMainMenu.
  • Add a UIDocument GameObject to the scene.
  • Verify the setup by entering Play mode with no errors.
Create a new project in Unity Hub
  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Unity Hub and press Enter to open it.
  • Click New project in the top-right corner.
  • At the top of the New project window, confirm the editor version is set to Unity 6 (any 6.3 release).
  • Under Core templates, select Universal 2D.
  • In the Project name field, type GameMainMenu.
  • Click Create project.

Unity Hub creates the project and opens it in the Unity Editor. You should see SampleScene loaded in the Hierarchy window.

What just happened?

Unity created a project folder with a default scene, camera, and render pipeline pre-configured for 2D development. The SampleScene in the Hierarchy is your working scene where all GameObjects live.

Don't see the project opening?

If Unity Hub asks you to download the template first, click Download template and wait for it to finish. Then click Create project again.

If the Editor takes a long time to open, this is normal for the first project. Unity is importing packages and compiling shaders.

Help me fix my Unity Hub project creation issue

Add a UIDocument to your scene

A UIDocument is a component that tells Unity to render UI Toolkit elements in your scene at runtime. Without one, your UXML layouts have nowhere to display.

  • In the top menu bar, click GameObject.
  • Hover over UI Toolkit.
  • Click UI Document.

A new UIDocument GameObject appears in the Hierarchy.

What did this create?

Unity auto-created three things for you:

  • A Panel Settings asset that controls how UI is rendered (resolution, scale mode).
  • A default runtime theme inside a UI Toolkit folder in your Assets.
  • A GameObject with a UIDocument component already attached and wired to the Panel Settings.
Verify the setup in Play mode

Before you enter Play mode, what do you expect to see in the Game view?

  • Click the Play button at the top center of the Editor toolbar.

The Game view shows an empty screen. This is correct. You have a UIDocument connected but no UI content inside it yet.

  • Open the Console window. If it is not visible, click Window in the top menu, then General, then Console.
  • Confirm there are no red error messages in the Console.
  • Click the Play button again to exit Play mode.

Seeing errors in the Console?

If you see a red error referencing a missing theme or Panel Settings, make sure the UIDocument component in the Inspector has a Panel Settings asset assigned. Unity usually assigns this automatically, but you can drag the asset from the Assets/UI Toolkit folder into the field manually.

Help me fix my UIDocument Console errors

Your canvas is ready. Next up, you'll open UI Builder and lay out the title screen with a game title and menu buttons.

Build the Title Screen Layout in UI Builder

Your scene has a UIDocument ready to display UI, but it has no content yet. The Game view is empty because no layout file is connected.

UI Builder is Unity's visual editor for creating UI layouts without writing code. In this step, you'll use it to build the title screen structure: a game title and three menu buttons.

In this step, get ready to:
  • Create a new UXML document in UI Builder.
  • Add a game title label and three menu buttons to the layout.
  • Connect the UXML file to the UIDocument and verify elements appear in Play mode.
Open UI Builder and create the UXML file

Before you can add any UI elements, you need a UXML file to hold them. UXML is Unity's XML-based markup language that defines UI structure, similar to HTML for web pages.

  • Open UI Builder by clicking Window in the top menu bar.
  • Select UI Toolkit, then UI Builder.
  • In the UI Builder window, click File at the top left of the Viewport, then select New.
  • A save dialog appears. Create a new folder called UI inside Assets.
  • Name the file MainMenu.uxml and save it inside Assets/UI.

The Hierarchy panel in UI Builder now shows your empty document. Time to add the first element.

  • In the Library panel (bottom left of UI Builder), find VisualElement under the Controls section.
  • Drag VisualElement into the Hierarchy panel.
  • With the new element selected, look at the Inspector panel on the right.
  • In the Name field at the top of the Inspector, type root.
  • Scroll down to the Flex section in the Inspector. Set Grow to 1.

You should see the root element listed in the Hierarchy panel. Setting Flex Grow to 1 tells this element to expand and fill all available screen space.

What is a VisualElement?

A VisualElement is the basic building block of UI Toolkit layouts. Think of it like a <div> in HTML.

It is an invisible container that holds and arranges other elements. You'll nest labels, buttons, and other containers inside it to build your menu structure.

Add the title screen elements

Now you'll build the actual menu structure inside the root container. Each element you add appears immediately in the Viewport.

  • In the Hierarchy panel, right-click on root and select Add > VisualElement.
  • Select the new child element in the Hierarchy.
  • In the Inspector, set its Name to title-screen.

This title-screen container will hold your game title and the buttons. Next, add the title label inside it.

  • In the Library panel, find Label under Controls.
  • Drag it into the Hierarchy panel and drop it inside the title-screen element (it should be nested as a child).
  • In the Inspector, set Name to game-title.
  • In the Inspector's Text field, type DRAGON QUEST.

You should now see "DRAGON QUEST" appear in the Viewport. Next, add a container for the buttons.

  • Right-click on title-screen in the Hierarchy and select Add > VisualElement.
  • Name this new element button-container.
  • In the Library panel, find Button under Controls.
  • Drag a Button into button-container. Set its Text to Play and its Name to play-button.
  • Drag a second Button into button-container. Set its Text to Settings and its Name to settings-button.
  • Drag a third Button into button-container. Set its Text to Quit and its Name to quit-button.

Your Viewport should now show the "DRAGON QUEST" label and three buttons stacked below it. They look plain and unstyled right now. That is expected.

What should the Hierarchy look like?

Your Hierarchy panel should show this nested structure:

  • root (top-level)
  • title-screen (child of root)
  • game-title (child of title-screen)
  • button-container (child of title-screen)
  • play-button, settings-button, quit-button (children of button-container)

Don't see text in the Viewport?

If the buttons or label appear blank, double-check that you filled in the Text field in the Inspector (not just the Name field). The Name field identifies the element in code. The Text field controls what displays on screen.

If you accidentally dropped an element at the wrong level, drag it within the Hierarchy to reparent it under the correct container.

Help me fix my UI Builder layout

Connect the UXML and verify in Play mode

The UXML file defines your layout, but the scene's UIDocument still does not know about it. You need to connect them.

  • Save your work in UI Builder by clicking File > Save in the Viewport toolbar (or press Cmd+S on macOS / Ctrl+S on Windows while UI Builder is focused).
  • Switch back to the Scene view by clicking the Scene tab.
  • In the Hierarchy panel, select the UIDocument GameObject.
  • In the Project window, navigate to Assets/UI.
  • Drag MainMenu.uxml from the Project window into the Source Asset field of the UIDocument component in the Inspector.

What does Source Asset do?

The Source Asset field tells the UIDocument component which UXML file to load at runtime. When you enter Play mode, Unity reads this file and renders the UI elements you defined in UI Builder.

Before you hit Play, what do you think you'll see in the Game view? Remember, you have not added any styling yet.

  • Click the Play button at the top of the Editor to enter Play mode.

You should see "DRAGON QUEST" displayed as plain white text, along with three unstyled buttons labeled Play, Settings, and Quit. This confirms the UXML is connected and rendering correctly.

  • Click Play again to exit Play mode.

Don't see any UI in the Game view?

Check that the Source Asset field on the UIDocument component shows MainMenu. If it is empty, the UXML file was not assigned.

Make sure you saved in UI Builder (File > Save) before assigning the file. The regular Ctrl+S does not save UI Builder documents unless the UI Builder window is focused.

Also check the Console window for any errors. If you see none and the Game view is still blank, confirm the UIDocument GameObject is active in the Hierarchy (the checkbox next to its name should be checked).

Help me troubleshoot my UIDocument connection

✔️ Awesome, I've got everything!

Great. Double-check you saved your UXML file and exited Play mode before continuing.

ⓧ I'd like to double check the full code

Open MainMenu.uxml in a text editor (right-click the file in the Project window and select Open). Your structure should match this:

<ui:UXML xmlns:ui="UnityEngine.UIElements" editor-extension-mode="False">
    <ui:VisualElement name="root">
        <ui:VisualElement name="title-screen">
            <ui:Label text="DRAGON QUEST" name="game-title" />
            <ui:VisualElement name="button-container">
                <ui:Button text="Play" name="play-button" />
                <ui:Button text="Settings" name="settings-button" />
                <ui:Button text="Quit" name="quit-button" />
            </ui:VisualElement>
        </ui:VisualElement>
    </ui:VisualElement>
</ui:UXML>

Your file may look slightly different

UI Builder may add extra attributes like inline styles (from setting Flex Grow) or additional schema references. As long as the element names and nesting order match, your file is correct.

Your title screen layout is built and rendering at runtime. Next up, you'll style it with USS to make it look like a real game menu.

Style the Menu with USS

Your menu elements are on screen, but they look like plain white text on a grey background. That is not exactly the polished game menu you are building.

USS (Unity Style Sheets) works like CSS for the web. It lets you control colors, fonts, spacing, and layout from a single file that applies to every matching element. In this step, you will create a stylesheet, connect it to your elements, and write the rules that transform your menu into a dark-themed, professional-looking title screen.

In this step, get ready to:
  • Create a USS file and link it to your UXML in UI Builder.
  • Assign style classes to each element so USS selectors can target them.
  • Write styling rules for layout, title, and buttons.
Create the stylesheet and assign classes

Before you can write any styling rules, you need a USS file linked to your UXML and class names on each element so the selectors know what to target.

  • In the Project window, navigate to the Assets/UI folder.
  • Right-click inside the folder, then select Create > UI Toolkit > Style Sheet.
  • Name the new file MainMenu.uss.
  • Open MainMenu.uxml in UI Builder by double-clicking it in the Project window.
  • In the StyleSheets panel (bottom-left of UI Builder), click the + dropdown.
  • Select Add Existing USS and choose MainMenu.uss from the file dialog.

You should see MainMenu.uss appear in the StyleSheets panel.

Now assign a class to each element so your USS selectors can find them.

  • In UI Builder's Hierarchy, select the root element.
  • In the Inspector on the right, find the Style Class List field.
  • Type root and click Add Style Class to List.
  • Select title-screen in the Hierarchy, type screen in the Style Class List field, and click Add Style Class to List.
  • Select game-title, type game-title, and click Add Style Class to List.
  • Select button-container, type button-container, and click Add Style Class to List.
  • Select play-button, type menu-button, and click Add Style Class to List.
  • Repeat for settings-button and quit-button, adding the class menu-button to each.
  • Save the UXML by selecting File > Save in UI Builder.

What are style classes?

A style class is a label you attach to an element so a USS selector can target it. The class menu-button on all three buttons means one USS rule styles all of them at once.

This is the same pattern as CSS classes on the web. One rule, many elements.

✔️ Awesome, I've got everything!

Great. Double check you saved the UXML in UI Builder before moving on.

ⓧ I'd like to double check the full code

Your MainMenu.uxml should now look like this (UI Builder may format attributes slightly differently, but the names and classes must match):

<ui:UXML xmlns:ui="UnityEngine.UIElements" editor-extension-mode="False">
    <Style src="project://database/Assets/UI/MainMenu.uss" />
    <ui:VisualElement name="root" class="root">
        <ui:VisualElement name="title-screen" class="screen">
            <ui:Label text="DRAGON QUEST" name="game-title" class="game-title" />
            <ui:VisualElement name="button-container" class="button-container">
                <ui:Button text="Play" name="play-button" class="menu-button" />
                <ui:Button text="Settings" name="settings-button" class="menu-button" />
                <ui:Button text="Quit" name="quit-button" class="menu-button" />
            </ui:VisualElement>
        </ui:VisualElement>
    </ui:VisualElement>
</ui:UXML>
Write the layout and title styles

With classes assigned, every rule you write in the USS file immediately applies to the matching elements.

  • Open MainMenu.uss in a text editor by double-clicking it in the Project window, then paste the following styles:
/* Fill the screen with a dark background, center all children */
.root {
    flex-grow: 1;
    background-color: rgb(30, 30, 46);
    align-items: center;
    justify-content: center;
}

/* Center the contents of each screen panel */
.screen {
    align-items: center;
    justify-content: center;
}

/* Large, bold, light-colored title text */
.game-title {
    font-size: 48px;
    color: rgb(205, 214, 244);
    -unity-font-style: bold;
    margin-bottom: 40px;
}

/* Center buttons horizontally */
.button-container {
    align-items: center;
}

What does this code do?

  • .root uses flex-grow: 1 to fill the entire screen, sets a dark purple background, and centers children both horizontally and vertically using Flexbox layout.
  • .screen centers the title and button group inside the panel.
  • .game-title sets the font to 48 pixels, a soft white color, bold weight, and adds space below it so the buttons do not crowd the title.
  • .button-container centers the buttons horizontally within the screen.
  • Save MainMenu.uss.
  • Return to the Unity Editor and enter Play mode.

You should see the dark background fill the screen with the title "DRAGON QUEST" displayed large and centered. The buttons are still plain-looking at this point.

Still seeing a grey background?

  • Confirm MainMenu.uss appears in the StyleSheets panel inside UI Builder. If it is missing, the USS is not linked to the UXML.
  • Check that you added the class root to the root element. Without the class, the .root selector has nothing to match.
  • Make sure you saved both the UXML (in UI Builder) and the USS file.

Still stuck? Help me debug why my USS styles are not applying to my UXML elements.

Style the menu buttons

The layout is set. Now give the buttons a consistent, polished appearance.

  • Return to MainMenu.uss in your text editor and add the following rule below the existing styles:
/* Dark rounded buttons with light text */
.menu-button {
    width: 200px;
    height: 50px;
    margin-top: 10px;
    margin-bottom: 10px;
    font-size: 20px;
    background-color: rgb(69, 71, 90);
    color: rgb(205, 214, 244);
    border-radius: 8px;
    border-width: 0;
}

What does this code do?

  • width and height give every button a fixed 200x50 pixel size so they line up neatly.
  • margin-top and margin-bottom add 10 pixels of breathing room between each button.
  • background-color sets a muted dark tone, while color makes the text a soft white that matches the title.
  • border-radius: 8px rounds the corners, and border-width: 0 removes the default border outline.
  • Save MainMenu.uss.

Before you enter Play mode, what do you expect the buttons to look like now?

  • Enter Play mode in the Unity Editor.

You should see a fully dark-themed menu. The title "DRAGON QUEST" is large and centered at the top, and three dark rounded buttons with light text are stacked vertically below it.

Buttons still look unstyled?

  • Verify that all three buttons have the class menu-button assigned. Select each button in UI Builder and check the Style Class List in the Inspector.
  • Ensure there are no typos in the selector name. The selector .menu-button must match the class name menu-button exactly (no leading dot in the class field).
  • Check that the USS file saved correctly and has no syntax errors. The Console window shows USS parse errors if any exist.

Still stuck? Help me figure out why my button styles are not applying in Unity UI Toolkit.

✔️ Awesome, I've got everything!

Great. Double check you saved MainMenu.uss before moving on.

ⓧ I'd like to double check the full code

Your MainMenu.uss should contain two sections. Scroll up and confirm you have both chunks in order:

  • The layout and title styles: .root, .screen, .game-title, and .button-container selectors.
  • The button styles: the .menu-button selector with width, height, colors, and border-radius.

Your menu now looks like a real game title screen. Next up, you will wire these buttons to actual behavior using C# scripting.

Wire Up Button Interactions with C#

Your menu looks polished, but clicking the buttons does nothing. The styling is purely visual.

C# scripting bridges the gap between what a player sees and what actually happens. In this step, you will write a script that uses UI Toolkit's event callback system to connect each button to real behavior.

In this step, get ready to:
  • Create a C# script that queries your UI elements by name.
  • Register click event callbacks so each button triggers an action.
  • Attach the script and verify button clicks in the Console.
Create the script and query UI elements

Before you can respond to button clicks, your script needs to find the buttons inside the visual tree. The Q<Button>() method queries elements by name, similar to querySelector in web development.

  • In the Project window, right-click inside the Assets folder.
  • Select Create > C# Script.
  • Name the script MainMenuController and press Enter.
  • Double-click MainMenuController.cs to open it in your code editor.
  • Delete all the default template code and paste the following:
using UnityEngine;
using UnityEngine.UIElements;

public class MainMenuController : MonoBehaviour
{
    private VisualElement _titleScreen;
    private VisualElement _settingsScreen;

    private void OnEnable()
    {
        // Get the UIDocument component and access its visual tree
        var uiDocument = GetComponent<UIDocument>();
        var root = uiDocument.rootVisualElement;

        // Store references to screen containers for navigation
        _titleScreen = root.Q("title-screen");
        _settingsScreen = root.Q("settings-screen");

        // Query each button by its name attribute
        var playButton = root.Q<Button>("play-button");
        var settingsButton = root.Q<Button>("settings-button");
        var quitButton = root.Q<Button>("quit-button");
        var backButton = root.Q<Button>("back-button");
    }
}

What does this code do?

GetComponent<UIDocument>() grabs the UIDocument sitting on the same GameObject. From there, rootVisualElement is the top of the visual tree (think of it like document in a web browser).

root.Q<Button>("play-button") searches the tree for a Button whose name attribute matches. Each query returns a typed reference you can attach events to.

The code also stores _titleScreen and _settingsScreen as fields. You will use these for screen navigation in the next step.

  • Save the file.
  • Switch back to Unity and wait for the spinner in the bottom-right corner to finish (Unity is compiling the script).
  • Check the Console window. You should see no red error messages.

Seeing a compilation error?

  • Make sure the filename is exactly MainMenuController.cs. The filename must match the class name.
  • Confirm you deleted ALL the default template code before pasting. Leftover using statements or class definitions will cause duplicate errors.
  • help me fix a compile error in my MainMenuController script
Register click callbacks and add handler methods

Now that you have references to each button, you can tell Unity what to do when a player clicks them. The RegisterCallback<ClickEvent> method wires a method to fire every time that button receives a click.

  • In MainMenuController.cs, find the closing brace } of the OnEnable method. Delete it and the class closing brace below it.
  • Paste the following code in their place to register callbacks and add the handler methods:
        // Register click callbacks for each button
        playButton.RegisterCallback<ClickEvent>(OnPlayClicked);
        settingsButton.RegisterCallback<ClickEvent>(OnSettingsClicked);
        quitButton.RegisterCallback<ClickEvent>(OnQuitClicked);
        backButton.RegisterCallback<ClickEvent>(OnBackClicked);
    }

    private void OnDisable()
    {
        var uiDocument = GetComponent<UIDocument>();
        var root = uiDocument.rootVisualElement;
        var playButton = root.Q<Button>("play-button");
        var settingsButton = root.Q<Button>("settings-button");
        var quitButton = root.Q<Button>("quit-button");
        var backButton = root.Q<Button>("back-button");
        playButton.UnregisterCallback<ClickEvent>(OnPlayClicked);
        settingsButton.UnregisterCallback<ClickEvent>(OnSettingsClicked);
        quitButton.UnregisterCallback<ClickEvent>(OnQuitClicked);
        backButton.UnregisterCallback<ClickEvent>(OnBackClicked);
    }

    private void OnPlayClicked(ClickEvent evt)
    {
        Debug.Log("Play button clicked! Game would start here.");
    }

    private void OnSettingsClicked(ClickEvent evt)
    {
        // To be implemented in next step
    }

    private void OnQuitClicked(ClickEvent evt)
    {
        Debug.Log("Quit button clicked!");
        Application.Quit();
    }

    private void OnBackClicked(ClickEvent evt)
    {
        // To be implemented in next step
    }
}

What does this code do?

RegisterCallback<ClickEvent> tells Unity to call your handler method every time the button is clicked. Each button points to a different method.

OnDisable mirrors OnEnable by unregistering every callback. This prevents memory leaks if the GameObject is disabled or destroyed.

OnSettingsClicked and OnBackClicked are empty stubs for now. You will fill them in the next step when you build the settings panel.

  • Save MainMenuController.cs.
  • Switch back to Unity and confirm the Console shows no errors after compilation finishes.

Seeing errors about missing methods?

  • Make sure you deleted the old closing brace of OnEnable before pasting. A duplicate brace will orphan the registration lines outside the method.
  • Check that the class closing brace } appears at the very end of the file. All methods must sit inside the class.
  • help me fix errors in my MainMenuController callback registration
Attach the script and test button clicks
  • In the Hierarchy window, select the UIDocument GameObject.
  • In the Inspector, click Add Component.
  • Type MainMenuController in the search field and select it from the list.

Before you enter Play mode, think about what you expect to happen when you click the Play button. Will something appear in the Console?

  • Click the Play button in the Unity toolbar to enter Play mode.
  • In the Game view, click the Play menu button.
  • Check the Console window. You should see the message Play button clicked! Game would start here. appear.
  • Click the Quit menu button. The Console should show Quit button clicked! appear.
  • Exit Play mode by clicking the Play button in the toolbar again.

Why doesn't Quit close the editor?

Application.Quit() only works in a built game, not in the editor. In Play mode it simply logs the message. When you export a final build, clicking Quit will actually close the application.

No Console messages when you click?

  • Confirm you attached MainMenuController to the UIDocument GameObject (not a different object). The script calls GetComponent<UIDocument>() on itself.
  • Make sure the button names in your UXML match exactly: play-button, settings-button, quit-button. A mismatch means Q<Button>() returns null.
  • Check that the Console filter buttons (the icons at the top) are not hiding log messages. Click the speech bubble icon to show Info logs.
  • help me figure out why my UI Toolkit button clicks aren't registering

✔️ Awesome, I've got everything!

Great. Double check you have saved MainMenuController.cs and that the Console shows no errors when you exit Play mode.

ⓧ I'd like to double check the full code

Your MainMenuController.cs was built across two code blocks above. Scroll up and confirm these sections are present, in order:

  • The using statements, class declaration, and OnEnable method (queries all elements and registers four callbacks).
  • The OnDisable method (unregisters all four callbacks).
  • Four handler methods: OnPlayClicked, OnSettingsClicked, OnQuitClicked, OnBackClicked.
  • A single class closing brace } at the very end.

Your buttons are alive. In the next step, you will build the settings panel and wire up OnSettingsClicked and OnBackClicked to show and hide screens.

Add a Settings Panel with Screen Navigation

Your menu looks polished and responds to clicks for Play and Quit. But clicking the Settings button does nothing at all.

A real game menu has multiple screens that players move between. In this step, you'll build a settings panel and wire up show/hide logic using DisplayStyle toggling. This is the standard UI Toolkit pattern for screen navigation.

In this step, get ready to:
  • Build a settings screen with a volume slider, fullscreen toggle, and back button in UI Builder.
  • Style the new elements with USS rules that match your dark theme.
  • Wire up C# callbacks to show and hide screens when buttons are clicked.
Add the settings screen elements in UI Builder

The settings screen lives alongside the title screen in the same UXML document. It stays hidden by default and only appears when the player clicks Settings.

  • Open MainMenu.uxml in UI Builder by double-clicking it in the Project window under Assets/UI.
  • In the UI Builder Hierarchy panel, right-click the root element and select Create > VisualElement.
  • In the Inspector panel on the right, set the Name to settings-screen.
  • In the Inspector's Style Class List field, type screen and press Enter to add the class.

The settings-screen should now appear as a sibling to title-screen in the Hierarchy. Now add the child elements inside it.

  • Right-click settings-screen in the Hierarchy and select Create > Label.
  • Set its Name to settings-title, its Text to Settings, and add the class settings-title.
  • Right-click settings-screen again and select Create > Slider.
  • Set its Name to volume-slider, Label to Volume, Value to 75, High Value to 100, and add the class settings-control.
  • Right-click settings-screen and select Create > Toggle.
  • Set its Name to fullscreen-toggle, Label to Fullscreen, and add the class settings-control.
  • Right-click settings-screen and select Create > Button.
  • Set its Name to back-button, Text to Back, and add the class menu-button.

Now hide the settings screen by default so it only appears when the player clicks the Settings button.

  • Select settings-screen in the Hierarchy.
  • In the Inspector under Inlined Styles > Display, set it to None.
  • Save the UXML file using File > Save in UI Builder (or Cmd+S on macOS, Ctrl+S on Windows).

Check the UI Builder Hierarchy panel. You should see settings-screen at the same level as title-screen, with four children nested inside: settings-title, volume-slider, fullscreen-toggle, and back-button.

Elements not appearing in the right place?

If your elements ended up inside title-screen instead of alongside it, drag settings-screen in the Hierarchy so it sits directly under root at the same indentation level as title-screen.

help me fix the hierarchy of my settings-screen in UI Builder

Style the settings elements with USS

The new elements need styling to match your dark theme. You'll add two USS rules for the settings title and the controls.

  • Open Assets/UI/MainMenu.uss in your code editor.
  • Add the following two rules at the end of the file, after the existing .menu-button rule:
.settings-title {
    font-size: 36px;
    color: rgb(205, 214, 244);
    -unity-font-style: bold;
    margin-bottom: 30px;
}

.settings-control {
    width: 300px;
    margin-top: 10px;
    margin-bottom: 10px;
    color: rgb(205, 214, 244);
}

What do these rules do?

  • .settings-title styles the "Settings" heading with a 36px font size, light color, and bold weight. The bottom margin pushes the controls below it downward.
  • .settings-control gives the slider and toggle a fixed 300px width and consistent spacing. The light color ensures labels are readable against the dark background.
  • Save MainMenu.uss.
Wire up the screen navigation in C#

Your controller script already queries the settings screen and registers button callbacks. The show/hide logic works by toggling each panel's display style between DisplayStyle.None (hidden) and DisplayStyle.Flex (visible).

  • Open Assets/MainMenuController.cs in your code editor.
  • Find the OnSettingsClicked method. It currently looks like this:
private void OnSettingsClicked(ClickEvent evt)
{
    // To be implemented in next step
}
  • Replace the comment with the show/hide logic so the method looks like this:
private void OnSettingsClicked(ClickEvent evt)
{
    // Hide the title screen and show the settings screen
    _titleScreen.style.display = DisplayStyle.None;
    _settingsScreen.style.display = DisplayStyle.Flex;
}
  • Now find the OnBackClicked method. It currently looks like this:
private void OnBackClicked(ClickEvent evt)
{
    // To be implemented in next step
}
  • Replace the comment with the reverse logic so the method looks like this:
private void OnBackClicked(ClickEvent evt)
{
    // Hide the settings screen and show the title screen
    _settingsScreen.style.display = DisplayStyle.None;
    _titleScreen.style.display = DisplayStyle.Flex;
}

Why DisplayStyle.None and DisplayStyle.Flex?

DisplayStyle.None completely removes an element from rendering and layout. Pointer events ignore it too.

DisplayStyle.Flex brings it back into the normal layout flow. Toggling between these two values is the standard UI Toolkit pattern for showing and hiding panels without destroying them.

  • Save MainMenuController.cs.
Test the full navigation flow

Before you hit Play, predict what will happen when you click Settings. Will both panels show at once, or will only one be visible at a time?

  • Return to the Unity Editor and wait for it to finish compiling (check the bottom-left status bar).
  • Click the Play button in the toolbar to enter Play mode.
  • Click the Settings button in the Game view.

The title screen disappears and the settings panel takes its place. You should see the "Settings" heading, a Volume slider, a Fullscreen toggle, and a Back button.

  • Click the Back button.

The settings panel hides and the title screen returns with all three original buttons. Only one panel is ever visible at a time.

  • Click Play in the toolbar again to exit Play mode.

Settings panel not appearing when you click?

  • Check that your settings-screen element in UI Builder has the name exactly as settings-screen. The C# script queries by this exact name.
  • Make sure you saved both MainMenu.uxml in UI Builder AND MainMenuController.cs in your code editor. Unity won't pick up unsaved changes.
  • Verify there are no red errors in the Console window. A typo in the C# file prevents compilation.

help me debug why my settings panel isn't showing up

✔️ Awesome, I've got everything!

Great. Make sure you've saved all three files before moving on.

ⓧ I'd like to double check the full code

Here is the complete MainMenu.uxml as it should look now:

<ui:UXML xmlns:ui="UnityEngine.UIElements" editor-extension-mode="False">
    <Style src="project://database/Assets/UI/MainMenu.uss" />
    <ui:VisualElement name="root" class="root">
        <ui:VisualElement name="title-screen" class="screen">
            <ui:Label text="DRAGON QUEST" name="game-title" class="game-title" />
            <ui:VisualElement name="button-container" class="button-container">
                <ui:Button text="Play" name="play-button" class="menu-button" />
                <ui:Button text="Settings" name="settings-button" class="menu-button" />
                <ui:Button text="Quit" name="quit-button" class="menu-button" />
            </ui:VisualElement>
        </ui:VisualElement>
        <ui:VisualElement name="settings-screen" class="screen" style="display: none;">
            <ui:Label text="Settings" name="settings-title" class="settings-title" />
            <ui:Slider label="Volume" value="75" high-value="100" name="volume-slider" class="settings-control" />
            <ui:Toggle label="Fullscreen" name="fullscreen-toggle" class="settings-control" />
            <ui:Button text="Back" name="back-button" class="menu-button" />
        </ui:VisualElement>
    </ui:VisualElement>
</ui:UXML>

For MainMenu.uss, confirm you have all seven rules in this order: .root, .screen, .game-title, .button-container, .menu-button, .settings-title, and .settings-control.

For MainMenuController.cs, confirm that OnSettingsClicked hides _titleScreen and shows _settingsScreen, and OnBackClicked does the reverse.

Your game menu now has full screen navigation. Players can move between the title screen and settings panel seamlessly. Next up, you'll take it further with animated hover effects in the Secret Mission.

Secret mission

Add Animated Hover Transitions

Your menu works, but it feels static. Professional game menus have subtle animations that make them feel alive. In this secret mission, you'll add smooth hover transitions so buttons scale up and change color when your mouse passes over them. The best part? It's all done in USS with zero additional C# code.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely locally inside Unity, so there are no ongoing costs.

Resources you used:

  • The GameMainMenu Unity project folder (contains MainMenu.uxml, MainMenu.uss, MainMenuController.cs, and auto-generated assets).

Keep everything running

No action needed. Choose this if you plan to keep building on your game menu or want to revisit the project later.

  • Your GameMainMenu project stays in Unity Hub's project list and on disk.
  • You can reopen it anytime from Unity Hub.

Pause - I'll come back to this later

Close Unity to free up memory. Your project files remain on disk for next time.

  • Save any unsaved changes in Unity (File > Save).
  • Close the Unity Editor.
  • Your project stays listed in Unity Hub. Reopen it anytime by clicking its name.

Delete - I don't want to use this again

Remove the entire project from your machine.

  • Open Unity Hub and find GameMainMenu in the Projects list. Note the file path shown below the project name.
  • Right-click the project and select Remove project from list.
  • Open your file manager (Finder on macOS or File Explorer on Windows) and navigate to the folder path you noted.
  • Delete the entire GameMainMenu folder.

Nice Work!

Nice Work!

Nice work! You just built a fully styled, interactive game main menu from scratch using Unity's modern UI Toolkit system.

Here's what you accomplished:

  • Built a complete menu layout with UXML using UI Builder, and styled it with USS using Flexbox layout, dark-themed colors, and rounded buttons.
  • Wired up button interactions using C# event callbacks and the Q() query method to connect UI elements to game logic.
  • Implemented screen navigation between a title screen and settings panel by toggling DisplayStyle.None and DisplayStyle.Flex in C#.
  • Secret Mission: Added smooth hover animations using USS transitions and the :hover pseudo-class so buttons scale up and change color when the mouse hovers over them.

Ready to quiz yourself?