Skip to main content

Scene Overview

The game consists of three Unity scenes that handle the complete game flow:
Assets/Scenes/
├── Title.unity      # Main menu and game start
├── Gameplay.unity   # Core platformer gameplay
└── Ending.unity     # Game over / completion screen

Scene Flow

The game follows a linear scene progression:
  1. Title - Player starts the game
  2. Gameplay - Player navigates the platformer level
  3. Ending - Shows final score and offers replay options

Scene Management Scripts

All scene logic is located in Assets/Scripts/SceneLogic/ and handles scene transitions and game state management. Location: Assets/Scripts/SceneLogic/MainMenu.cs:4 Handles the title screen and game initialization.
using UnityEngine;
using UnityEngine.SceneManagement;

public class MainMenu : MonoBehaviour
{
    public void StartGame()
    {
        SceneManager.LoadScene("Gameplay");
    }
}
Responsibilities:
  • Provides StartGame() method called by UI button
  • Transitions from Title scene to Gameplay scene
  • Simple, stateless scene transition
Usage: Attached to a GameObject in the Title scene and invoked by the “Start Game” UI button’s OnClick event.

FinishGame.cs

Location: Assets/Scripts/SceneLogic/FinishGame.cs:6 Handles level completion and player death scenarios using an event-driven approach.
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;

public class FinishGame : MonoBehaviour
{
    public static event Action OnDeathEvent;     // Player death
    public static event Action OnFinishedEvent;  // Level completion

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (gameObject.CompareTag("Spike") || 
            gameObject.CompareTag("DeathDetector"))
        {
            StartCoroutine(BreakBetweenScenes());
        }
        else
        {
            OnFinishedEvent?.Invoke();
            ChangeScene();
        }
    }

    private IEnumerator BreakBetweenScenes()
    {
        OnDeathEvent?.Invoke();
        yield return new WaitForSecondsRealtime(0.75f);
        ChangeScene();
    }

    private void ChangeScene()
    {
        SceneManager.LoadScene("Ending");
    }
}
Responsibilities:
  • Detects level completion (reaching finish line)
  • Handles player death (collision with spikes or fall detection)
  • Broadcasts events for death and completion
  • Manages transition delay for death feedback (0.75s)
  • Transitions to Ending scene
Key Features:
The script uses C# events to notify other systems:
  • OnDeathEvent - Triggered when player dies (used by MusicManager.cs:16 and ScoreSystem.cs:14)
  • OnFinishedEvent - Triggered on successful completion (used by ScoreSystem.cs:15)
This decouples scene logic from audio and scoring systems.
When the player dies:
  1. Collision detected with “Spike” or “DeathDetector” tag
  2. OnDeathEvent is invoked (triggers death sound)
  3. 0.75-second delay allows feedback to play
  4. Scene transitions to Ending
Attached to multiple GameObjects:
  • Finish line trigger (success path)
  • Spike obstacles (death path)
  • Fall detection zone (death path)

ResetGame.cs

Location: Assets/Scripts/SceneLogic/ResetGame.cs:4 Provides gameplay restart functionality from the ending screen.
using UnityEngine;
using UnityEngine.SceneManagement;

public class ResetGame : MonoBehaviour
{
    public void ResetGameToGameplay()
    {
        SceneManager.LoadScene("Gameplay");
    }
}
Responsibilities:
  • Reloads Gameplay scene for replay
  • Called by “Try Again” or “Replay” button
  • Resets all gameplay state by reloading the scene
Usage: Attached to a GameObject in the Ending scene and triggered by a UI button for replaying the game.

QuitGame.cs

Location: Assets/Scripts/SceneLogic/QuitGame.cs:4 Handles application exit with editor-safe implementation.
using UnityEngine;
using UnityEngine.InputSystem;

public class QuitGame : MonoBehaviour
{
    public void Update()
    {
        if ((Keyboard.current != null) && 
            Keyboard.current.escapeKey.wasPressedThisFrame)
        {
            Quit();
        }
    }

    public void Quit()
    {
        #if UNITY_EDITOR
            UnityEditor.EditorApplication.isPlaying = false;
        #else
            Application.Quit();
        #endif
    }
}
Responsibilities:
  • Exits the application when requested
  • Supports ESC key for quick exit
  • Can be called by UI buttons
  • Editor-safe implementation (stops play mode instead of crashing)
Key Features:
Uses Unity’s new Input System (UnityEngine.InputSystem):
  • Checks for ESC key press each frame
  • wasPressedThisFrame ensures single trigger per press
  • Null-checks keyboard to prevent errors
Conditional compilation for different environments:
  • Editor: Stops play mode without crashing Unity
  • Build: Properly exits the application

Scene Transition Patterns

The project uses two main patterns for scene transitions:

Direct Loading

Immediate scene transitions for instant feedback:
SceneManager.LoadScene("Gameplay");
Used by:
  • MainMenu.cs - Start game
  • ResetGame.cs - Replay game

Delayed Loading

Transitions with delay for feedback:
private IEnumerator BreakBetweenScenes()
{
    OnDeathEvent?.Invoke();  // Play death sound/animation
    yield return new WaitForSecondsRealtime(0.75f);
    ChangeScene();
}
Used by:
  • FinishGame.cs - Death scenario (allows death sound/animation)

Scene Dependencies

Gameplay Scene

Requires these active systems:
  • Player GameObject with PlayerInput and PlayerJump components
  • ScoreSystem for tracking collected coins
  • MusicManager for audio feedback
  • CameraController for camera following
  • Finish line with FinishGame component
  • Obstacles with FinishGame component (tagged “Spike” or “DeathDetector”)

Ending Scene

Dependencies:
  • ShowFinalScore script to display ScoreSystem.FinalScore
  • UI buttons connected to ResetGame.ResetGameToGameplay()
  • Optional quit button connected to QuitGame.Quit()

Title Scene

Minimal dependencies:
  • UI button connected to MainMenu.StartGame()
  • Optional QuitGame component for ESC key handling

Event-Driven Scene Logic

Scene transitions trigger events that other systems subscribe to:
// FinishGame.cs broadcasts:
OnDeathEvent?.Invoke();      // Death occurred
OnFinishedEvent?.Invoke();   // Level completed

// Subscribers in other scripts:
// MusicManager.cs:14
FinishGame.OnDeathEvent += SetDeathEffect;

// ScoreSystem.cs:14
FinishGame.OnDeathEvent += WriteFinalScore;
FinishGame.OnFinishedEvent += WriteFinalScore;
This pattern allows scene logic to remain simple while other systems respond appropriately to scene events.

Build docs developers (and LLMs) love