๐Ÿ”ท My First Unity Game ยท Episode 7 of 8 ยท See All Episodes
๐Ÿ“‹ Episode 7 ยท Improver+ ยท The Professional Layer

Menus Matter!
UI & Menus

The layer every real game needs: a title screen, settings with working volume and quality options that SAVE, a pause menu, smooth fades and juicy button feedback, wrapped around your RPG.

๐Ÿ‘ถ Ages 12+ โฑ๏ธ ~2 Hours ๐Ÿ”ท Unity & C# โœ“ Free
๐Ÿ–ฅ๏ธ Canvas & anchors ๐Ÿ”˜ Buttons & events โธ๏ธ Pause menu ๐ŸŽš๏ธ Sliders & volume ๐Ÿ’พ PlayerPrefs ๐ŸŽž๏ธ Fade transitions
โญ
0 XP
Level 1
๐Ÿ”ฅ0
Your Progress 0 / 6 steps
1
๐Ÿ–ฅ๏ธ
Canvas & Anchors
UI that survives every screen size
Active
๐ŸŽฏ
Goal for this step

Understand the Canvas system and build a resolution-proof layout.

  • 1New scene MainMenu. UI โ†’ Canvas; set Canvas Scaler to Scale With Screen Size, reference 1920ร—1080, the setting that makes UI work on every monitor.
  • 2Anchors are the key concept: a corner-anchored element stays that distance from that corner at ANY resolution. Centre-anchored stays centred.
  • 3Build: big title text (top-centre anchored), a vertical group of buttons (centre), version text (bottom-left corner).
  • 4Test: drag the Game view to silly sizes. Nothing breaks. That is anchors working.
โœ๏ธ
Fill in the Blanks
+15 XP
Resolution independence comes from the Canvas Scaler set to Scale With Size. Elements pin themselves to screen regions via .
๐Ÿง 
Knowledge Check
+15 XP
A minimap pinned to the top-right on every monitor size is achieved withโ€ฆ
AA very wide image
BAnchoring the element to the top-right corner, it keeps its offset from THAT corner
CUpdating position in code every frame
2
๐Ÿ”˜
Buttons That Do Things
OnClick events, hover states and scene flow
Locked
๐ŸŽฏ
Goal for this step

Wire the menu buttons to real actions.

  • 1A MenuActions script with public methods: PlayGame() (LoadScene), OpenSettings(), QuitGame().
  • 2Each Buttonโ€™s OnClick list in the Inspector: + โ†’ drag the scriptโ€™s object โ†’ pick the method. Visual event wiring.
  • 3Button feel: set Transition to Color Tint (subtle), and add a tiny scale punch on hover with an EventTrigger or a small script. Buttons must FEEL clickable.
  • 4Application.Quit() does nothing in the editor, wrap it so you can still test.
MenuActions.cs
using UnityEngine;
using UnityEngine.SceneManagement;

public class MenuActions : MonoBehaviour
{
    public void PlayGame()  { SceneManager.LoadScene("Village"); }

    public void QuitGame()
    {
#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
#else
        Application.Quit();
#endif
    }
}
โœ๏ธ
Fill in the Blanks
+15 XP
Buttons call code through their event list in the Inspector. Application. only works in a built game, not the editor.
๐Ÿง 
Knowledge Check
+15 XP
The #if UNITY_EDITOR block exists becauseโ€ฆ
AEditors are slow
BQuit does nothing inside the editor, the compile-time switch gives you a testable quit in both worlds
CIt is decoration
3
โธ๏ธ
The Pause Menu
timeScale, a panel, and the resume flow
Locked
๐ŸŽฏ
Goal for this step

Add a working pause menu to the game scenes.

  • 1In the game scene: a full-screen semi-transparent panel (inactive by default) with Resume / Settings / Main Menu buttons.
  • 2PauseManager: Escape toggles, Time.timeScale = 0 freezes physics, coroutines with WaitForSeconds, everything time-based; the panel appears.
  • 3Gotcha you now know: timeScale survives scene loads, ALWAYS set it back to 1 when leaving to the menu (your Episode 3 restart already did!).
  • 4Any UI animation that must run while paused uses unscaled time.
PauseManager.cs
using UnityEngine;

public class PauseManager : MonoBehaviour
{
    public GameObject pausePanel;
    bool paused;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            paused = !paused;
            pausePanel.SetActive(paused);
            Time.timeScale = paused ? 0f : 1f;
        }
    }
}
โŒจ๏ธ
Code Challenge
+20 XP
Toggle the pause state:
PauseManager.cs
paused = ;
pausePanel.SetActive(paused);
Time.timeScale = paused ?  : ;
๐Ÿ’ก Hint: Flip the boolean; zero time when paused, full speed when not.
๐Ÿง 
Knowledge Check
+15 XP
Why does Time.timeScale = 0 pause "everything" so effectively?
AIt stops the CPU
BPhysics, animation and deltaTime all multiply by it, zero scales the whole simulation to a standstill
CIt hides the scene
4
๐ŸŽš๏ธ
Settings: Sliders & Toggles
Volume, quality dropdown and fullscreen toggle
Locked
๐ŸŽฏ
Goal for this step

Build a settings panel whose controls actually work.

  • 1Settings panel: a volume Slider (0-1), a quality Dropdown, a fullscreen Toggle.
  • 2Each control has an OnValueChanged event, same wiring as buttons.
  • 3Volume: AudioListener.volume = value; (one global line for now, mixers come later in your journey).
  • 4Quality: QualitySettings.SetQualityLevel(index). Fullscreen: Screen.fullScreen = isOn.
  • 5Move the slider while music plays, live feedback sells settings.
SettingsMenu.cs
using UnityEngine;

public class SettingsMenu : MonoBehaviour
{
    public void SetVolume(float value)
    {
        AudioListener.volume = value;
    }

    public void SetQuality(int index)
    {
        QualitySettings.SetQualityLevel(index);
    }

    public void SetFullscreen(bool isOn)
    {
        Screen.fullScreen = isOn;
    }
}
โœ๏ธ
Fill in the Blanks
+15 XP
Sliders and toggles fire their event when adjusted. Global game volume is one line: AudioListener..
๐Ÿง 
Knowledge Check
+15 XP
Settings controls pass their new value INTO your method automatically becauseโ€ฆ
AMagic
BThe event system supports dynamic parameters, pick the "Dynamic float" version of your method when wiring
CUnity reads variable names
5
๐Ÿ’พ
PlayerPrefs: Settings That Stick
Save and load preferences across sessions
Locked
๐ŸŽฏ
Goal for this step

Persist every setting so it survives quitting the game.

  • 1PlayerPrefs is Unityโ€™s built-in key-value store: SetFloat/SetInt/GetFloat/GetInt, localStorage for Unity!
  • 2Save each setting when it changes; load them all in Start (with sensible defaults as the second Get argument).
  • 3Also apply loaded values back to the UI controls so sliders show the truth.
  • 4Quit fully, relaunch, your volume remembered. Small feature, huge respect from players.
SettingsMenu.cs (persistence)
public Slider volumeSlider;

void Start()
{
    float vol = PlayerPrefs.GetFloat("volume", 1f);
    AudioListener.volume = vol;
    volumeSlider.value = vol;      // sync the UI
}

public void SetVolume(float value)
{
    AudioListener.volume = value;
    PlayerPrefs.SetFloat("volume", value);
}
โŒจ๏ธ
Code Challenge
+20 XP
Load the saved volume with a default:
SettingsMenu.cs
float vol = PlayerPrefs.("volume", );
volumeSlider. = vol;
๐Ÿ’ก Hint: Read the stored float; the second argument is the first-run default; then push it into the slider so UI matches reality.
๐Ÿง 
Knowledge Check
+15 XP
PlayerPrefs is Unityโ€™s equivalent of which tool from your browser games?
AThe canvas
BlocalStorage, a persistent key-value store for small data like settings and high scores
CrequestAnimationFrame
6
๐ŸŽž๏ธ
Fades & Final Polish
Scene transitions and the pro checklist
Locked
๐ŸŽฏ
Goal for this step

Add fade-to-black transitions and complete the UI layer.

  • 1A persistent full-screen black Image (alpha 0, Raycast Target off so it never blocks clicks!) + a Fader script.
  • 2Coroutine fades: alpha 0โ†’1, LoadScene, 1โ†’0. Every door and menu button now goes through the fader. Instant production feel.
  • 3Use unscaled time in the fade so it works even from the paused menu.
  • 4Final checklist: title โœ“ settings that save โœ“ pause โœ“ fades โœ“ hover feedback โœ“. Players never praise good UI, they just stop noticing it. That is the goal.
  • 5One episode left. It is the big one: MULTIPLAYER.
Fader.cs
IEnumerator FadeAndLoad(string scene)
{
    for (float a = 0; a < 1; a += Time.unscaledDeltaTime * 2f)
    {
        black.color = new Color(0, 0, 0, a);
        yield return null;
    }
    SceneManager.LoadScene(scene);
    for (float a = 1; a > 0; a -= Time.unscaledDeltaTime * 2f)
    {
        black.color = new Color(0, 0, 0, a);
        yield return null;
    }
}
โœ๏ธ
Fill in the Blanks
+15 XP
The fade uses delta time so it runs even while paused, and the black image must have Raycast disabled so it never blocks buttons.
๐Ÿง 
Knowledge Check
+15 XP
yield return null inside the fade loop meansโ€ฆ
AStop the fade
B"Wait one frame", the loop advances the alpha a little every frame, creating the smooth fade
CReturn no scene
๐ŸŽ‰๐Ÿ†๐ŸŽฎโœจ๐ŸŽ‰
Workshop Complete!
Title, settings, pause, saving, transitions, the professional wrapper is on. One episode remains: multiplayer!
0
Total XP
1
Level
0
Best Streak
0%
Accuracy
โ–ถ Episode 8: Multiplayer Basics โ†’
โญ View My Progress & Certificates

This workshop was free and took many hours to build. If it helped you learn something new, consider supporting the project.

☕ Support on Ko-fi