U
tab 01Basics11 lessons — tap to open
10 / 11 · 16 min
Basics

Screens, panels and the GameManager

your project so far

Assets/

Scenes/

Arena.unity

GameManagerKnightMain CameraCanvasHudPanelPausePanel
Intro.unity

Scripts/

CharacterSwitcher.csIntroScreen.csGameManager.cs

Audio/

arena music (.ogg)click (.wav)

you already havethis lesson adds

Every game has one object that is not part of the world: it decides what you are looking at and what is coming out of the speakers. Before you write it, though, two words have to stop being interchangeable — because in Unity they are two completely different things.

Screen and panel are not the same word

✓ Screen

SceneManager.LoadScene("Arena")

A whole Unity scene, in its own .unity file. Loading one destroys everything in the scene you were in and builds the new one from disk. You use it when a clean slate is exactly what you want.

✓ Panel

pausePanel.SetActive(true)

A GameObject inside the scene you are already in. Switching one changes nothing else — the floor, the blocks and the Knight stay exactly where they are. You use it for anything that sits on top of the game.
  • Different place, different world → screen. The intro is not the arena, so it gets a scene file of its own.

  • Same place, something on top → panel. Pausing happens in the arena, so it is a GameObject in the arena.

  • If you find yourself needing DontDestroyOnLoad to keep something alive across a switch, you almost certainly wanted a panel.

animated diagram

Two screens, each a scene file. Two panels, both living inside the second one. The arena underneath never moves.

Step 1 — the intro screen, a scene of its own

This is the one place in the whole course where a second scene earns its keep. The intro has no floor, no characters and no physics: it loads in a blink, and the moment you leave it there is nothing worth keeping.

  1. 1

    File▸New Scene → Basic (URP), then File▸Save As → Assets/Scenes/Intro.unity.

  2. 2

    Add GameObject▸UI▸Canvas, a Text with the game title, and a UI▸Button labelled PLAY.

  3. 3

    Create an empty object called Intro, attach IntroScreen.cs, and point the button's On Click () at LoadArena.

IntroScreen.cs — the entire intro screen
using UnityEngine;
using UnityEngine.SceneManagement;

public class IntroScreen : MonoBehaviour
{
    public void LoadArena()
    {
        SceneManager.LoadScene("Arena");
    }
}

Step 2 — one manager the whole arena can reach

Back in Arena.unity. A button needs to tell the manager to pause. A script on the Knight needs to play a hit sound. Neither of them owns the manager, and hunting for it with FindObjectOfType on every call is both slow and easy to get wrong. One static field settles it.

GameManager.cs — attach to the GameManager object you made last lesson
using UnityEngine;
using UnityEngine.SceneManagement;

// Panels, not screens: both of these live inside Arena.unity.
public enum GamePanel { Hud, Pause }

public class GameManager : MonoBehaviour
{
    // The whole arena reaches the manager through this one field.
    public static GameManager I;

    void Awake()
    {
        I = this;
    }
}

Step 3 — two panels inside the arena

  1. 1

    GameObject▸UI▸Canvas. Unity adds an EventSystem next to it — leave that alone, it is what makes buttons clickable.

  2. 2

    Inside the Canvas create two empty objects: HudPanel and PausePanel. Each one is just a container.

  3. 3

    HudPanel gets whatever you want visible while playing — a Text reading 0 will do. PausePanel gets a full-screen dark Image, the word PAUSED, a RESUME button and a MENU button.

GameManager.cs — add these to the class
[Header("Panels")]
public GameObject hudPanel;
public GameObject pausePanel;

public GamePanel current { get; private set; }

void Start()
{
    ShowPanel(GamePanel.Hud);   // the arena starts playable
}

public void ShowPanel(GamePanel next)
{
    current = next;
    hudPanel.SetActive(next == GamePanel.Hud);
    pausePanel.SetActive(next == GamePanel.Pause);

    // A pause panel that does not stop time is just a picture.
    Time.timeScale = next == GamePanel.Pause ? 0f : 1f;
}

void Update()
{
    if (Input.GetKeyDown(KeyCode.Escape))
        ShowPanel(current == GamePanel.Pause ? GamePanel.Hud : GamePanel.Pause);
}

// Leaving the arena is a screen change, so it goes through SceneManager.
public void BackToIntro()
{
    Time.timeScale = 1f;
    SceneManager.LoadScene("Intro");
}
  • One line per panel, and the comparison decides it. Add a third panel later and you add one line, not a new if-chain.

  • SetActive(false) stops that panel's Update too, so a hidden panel costs nothing per frame.

  • Point the RESUME button at ShowPanel and the MENU button at BackToIntro. One is a panel switch, the other is a screen load — same menu, two different kinds of jump.

Step 4 — music that loops, clicks that do not

Two AudioSources on the same GameManager object. One has Loop ticked and holds the music. The other holds nothing at all and fires one-shots on demand.

GameManager.cs — the sound half
[Header("Sound")]
public AudioSource musicSource;   // tick Loop on this one
public AudioSource sfxSource;
public AudioClip arenaMusic;
public AudioClip clickClip;

public void PlayMusic(AudioClip track)
{
    // Asking for the track that is already playing must not restart it.
    if (musicSource.clip == track && musicSource.isPlaying) return;

    musicSource.clip = track;
    musicSource.Play();
}

public void PlaySfx(AudioClip clip)
{
    if (clip != null) sfxSource.PlayOneShot(clip);
}

Where the sound actually comes out

  • An AudioListener is the ear, and a scene should have exactly one. Unity put it on the Main Camera in lesson 06 — leave it there, and remember Intro.unity has its own.

  • Music does not survive a screen change: load Intro and the arena's AudioSource is destroyed with the rest of the scene. That is the price of a screen, and it is why you do not make one lightly.

  • Clips live in Assets/Audio — the folder you made in lesson 05. .ogg for music, .wav for short effects.

  • Untick Play On Awake on both sources. The manager decides when sound starts, not the Inspector.

Step 5 — wire it up

  1. 1

    Select GameManager and add two Audio Source components. Tick Loop on the first, untick Play On Awake on both.

  2. 2

    In the Inspector drag HudPanel and PausePanel into their slots, the two Audio Sources into Music Source and Sfx Source, and your clips into Arena Music and Click Clip.

  3. 3

    Add PlayMusic(arenaMusic); to Start(), right after ShowPanel, so the arena comes up with the track already running.

  4. 4

    Open Intro.unity and press Play from there, not from the arena. That is the order a player meets them in, and it is the only way to catch a broken Build Settings list.

  • ✓Play from Intro.unity and PLAY takes you to the arena, with music.
  • ✓Escape brings up PausePanel and the Knight stops moving; Escape again and it carries on.
  • ✓The floor, the blocks and the three characters never move while a panel is switched.
  • ✓MENU returns to the intro, and the intro is not frozen when it gets there.