Singleton Pattern & Design Patterns Roadmap

Design Patterns Roadmap

The Singleton Pattern 🎯

CSCI 3213 - Game Programming

Spring '26 - Week 2, Class 1

Your journey through professional game patterns begins!

Today's Content

📚 Based on Chapter 4

Implementing a Game Manager with the Singleton

From: Game Development Patterns with Unity 2021 (2nd Edition)
By David Baron

Remember: Baron's book is available at Dulaney Browne Library. Today we're starting our practical pattern implementations!

Today's Agenda

What We'll Cover

  1. Part 1: Semester Patterns Roadmap (10 patterns)
  2. Part 2: Understanding the Singleton Pattern
  3. Part 3: Implementing a Game Manager
  4. Part 4: Testing the Singleton
  5. Homework: Complete implementation & video submission
Time Management: If we run short on time, you'll complete the implementation as homework. Either way, you'll need to test with 5 scenes!

Part 1: Design Patterns Roadmap

10 Patterns, 10 Weeks

Each pattern solves a specific game development problem.
Each week, we'll learn the theory and implement it in Blade Racer.

The Journey

By the end of this course, you'll have a complete game built with professional-grade architecture using industry-standard design patterns.

Foundational Patterns (Weeks 2-6)

CHAPTER 4 • WEEK 2
Singleton Pattern

Implementing a Game Manager

CHAPTER 5 • WEEK 3
State Pattern

Managing Character States

CHAPTER 6 • WEEK 4
Event Bus Pattern

Managing Game Events

CHAPTER 7 • WEEK 5
Command Pattern

Implementing a Replay System

CHAPTER 8 • WEEK 6
Object Pool Pattern

Optimizing Performance

Behavioral Patterns (Weeks 7-11)

CHAPTER 9 • WEEK 7
Observer Pattern

Decoupling Components

CHAPTER 10 • WEEK 8
Visitor Pattern

Implementing Power-Ups

CHAPTER 11 • WEEK 9
Strategy Pattern

Implementing a Drone

CHAPTER 12 • WEEK 10
Decorator Pattern

Weapon System Implementation

CHAPTER 13 • WEEK 11
Spatial Partition Pattern

Implementing a Level Editor

Your Learning Path

Pattern Categories

Creational: Singleton, Object Pool
Behavioral: State, Command, Observer, Visitor, Strategy
Structural: Decorator, Spatial Partition
Architectural: Event Bus
Don't worry about memorizing! We'll learn each pattern in context when we need it for Blade Racer.

Part 2: The Singleton Pattern

What is a Singleton?

A class that ensures only one instance exists
and provides global access to that instance.

Real-World Analogy

Like a country having only one president at a time. Everyone knows who the president is, and there can only be one person in that role.

The Problem Singleton Solves

❌ Without Singleton

// Player needs game manager GameManager manager = GameObject.Find("GameManager") .GetComponent<GameManager>(); // Enemy also needs game manager GameManager manager = GameObject.Find("GameManager") .GetComponent<GameManager>(); // UI also needs game manager... 😫

Problems: Repeated code, slow GameObject.Find(), no guarantee of single instance

✅ With Singleton

// Anywhere in your code: GameManager.Instance.StartGame(); GameManager.Instance.PauseGame();

Benefits: Clean, fast, guaranteed single instance, globally accessible

When to Use the Singleton Pattern

✅ Perfect For

  • Game Manager
  • Audio Manager
  • Input Manager
  • Save/Load Manager
  • Network Manager
  • Pool Manager

❌ Not Suitable For

  • Multiple instances needed
  • Player characters
  • Enemies
  • Projectiles
  • UI elements (usually)
  • Temporary objects
Rule of Thumb: If you need global access and only ONE instance should exist, use Singleton.

Singleton: Benefits & Drawbacks

✅ Benefits

  • Single Instance: Guaranteed only one exists
  • Global Access: Available from anywhere
  • Lazy Instantiation: Created when needed
  • Clean Code: No repeated GameObject.Find()
  • Performance: Fast direct access

⚠️ Drawbacks

  • Global State: Can create hidden dependencies
  • Testing: Harder to unit test
  • Coupling: Code becomes dependent on singleton
  • Overuse: Can become anti-pattern if abused
  • Threading: Not thread-safe by default
⚠️ Important: Don't make everything a Singleton! Use it judiciously for true manager classes.

Singleton Pattern Structure

Core Components

1. Private Static Instance

Stores the single instance

2. Public Static Accessor

Provides global access point (Instance property)

3. Private Constructor (optional)

Prevents external instantiation

4. Instance Check

Creates instance if it doesn't exist

Basic Singleton Implementation

using UnityEngine; public class GameManager : MonoBehaviour { // 1. Private static instance variable private static GameManager _instance; // 2. Public static accessor property public static GameManager Instance { get { if (_instance == null) { // Find existing instance in scene _instance = FindObjectOfType<GameManager>(); if (_instance == null) { // Create new GameObject with GameManager GameObject go = new GameObject("GameManager"); _instance = go.AddComponent<GameManager>(); } } return _instance; } } void Awake() { // Ensure only one instance exists if (_instance != null && _instance != this) { Destroy(this.gameObject); } else { _instance = this; } } }

Persistent Singleton (Don't Destroy)

void Awake() { if (_instance != null && _instance != this) { // Destroy duplicate Destroy(this.gameObject); } else { _instance = this; // Persist across scene loads! DontDestroyOnLoad(this.gameObject); } }

DontDestroyOnLoad()

Keeps the GameObject alive when loading new scenes. Perfect for managers that need to persist throughout the game!

Testing Note: You'll test this with 5 scenes to see it persist!

Generic Singleton (Reusable Template)

using UnityEngine; public class Singleton<T> : MonoBehaviour where T : Component { private static T _instance; public static T Instance { get { if (_instance == null) { _instance = FindObjectOfType<T>(); if (_instance == null) { GameObject obj = new GameObject(); obj.name = typeof(T).Name; _instance = obj.AddComponent<T>(); } } return _instance; } } public virtual void Awake() { if (_instance == null) { _instance = this as T; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } }
Generics Power! Remember from our crash course? Now any class can become a Singleton!

Using the Generic Singleton

// Simply inherit from Singleton<T> public class GameManager : Singleton<GameManager> { public void StartGame() { Debug.Log("Game Started!"); } } public class AudioManager : Singleton<AudioManager> { public void PlaySound(string soundName) { Debug.Log("Playing: " + soundName); } }
// Use them anywhere! public class Player : MonoBehaviour { void Start() { GameManager.Instance.StartGame(); AudioManager.Instance.PlaySound("PlayerSpawn"); } }

Part 3: Designing a Game Manager

What Does a Game Manager Do?

  • 🎮 Initialize game systems
  • ⏸️ Handle game state (Start, Pause, Resume, End)
  • 📊 Track game-wide data (score, time, level)
  • 🔄 Coordinate between systems
  • 💾 Manage scene transitions
For Blade Racer: Our Game Manager will initialize the race, track time, handle pause/resume, and manage race completion.

Game Manager Implementation

using UnityEngine; public class GameManager : Singleton<GameManager> { // Game state private bool _isGameActive; private float _gameTime; public override void Awake() { base.Awake(); // Call Singleton Awake } void Start() { InitializeGame(); } private void InitializeGame() { Debug.Log("[GameManager] Initializing game..."); _isGameActive = false; _gameTime = 0f; } public void StartGame() { Debug.Log("[GameManager] Game Started!"); _isGameActive = true; } public void PauseGame() { Debug.Log("[GameManager] Game Paused"); _isGameActive = false; Time.timeScale = 0f; } public void ResumeGame() { Debug.Log("[GameManager] Game Resumed"); _isGameActive = true; Time.timeScale = 1f; } void Update() { if (_isGameActive) { _gameTime += Time.deltaTime; } } }

Part 4: Testing the Singleton

Testing Strategy

  1. Create Test Script: TestGameManager.cs
  2. Call Instance: Verify global access works
  3. Test Methods: Call StartGame(), PauseGame(), etc.
  4. Multiple Scenes: Load 5 different scenes
  5. Verify Persistence: Confirm same instance across scenes
Your Homework: Create 5 test scenes and verify the Game Manager persists across all of them!

Test Script Example

using UnityEngine; using UnityEngine.SceneManagement; public class TestGameManager : MonoBehaviour { void Start() { // Test global access Debug.Log("Testing GameManager Singleton..."); // Start the game GameManager.Instance.StartGame(); } void Update() { // Test pause/resume if (Input.GetKeyDown(KeyCode.P)) { GameManager.Instance.PauseGame(); } if (Input.GetKeyDown(KeyCode.R)) { GameManager.Instance.ResumeGame(); } // Load next scene to test persistence if (Input.GetKeyDown(KeyCode.N)) { int nextScene = SceneManager.GetActiveScene().buildIndex + 1; if (nextScene < SceneManager.sceneCountInBuildSettings) { SceneManager.LoadScene(nextScene); } } } }

Setting Up Test Scenes

Step-by-Step Setup

  1. Create 5 new scenes: Scene1, Scene2, Scene3, Scene4, Scene5
  2. Add all scenes to Build Settings (File → Build Settings)
  3. In Scene1: Add GameObject with GameManager script
  4. In each scene: Add different colored background (visual verification)
  5. In each scene: Add GameObject with TestGameManager script
  6. Add UI Text showing scene name (optional but helpful)
Visual Test: Different background colors help you see when scenes change!

Testing Checklist

✅ Verify These Behaviors

✓ GameManager.Instance is accessible from any script
✓ Only ONE instance exists (check Hierarchy)
✓ Instance persists across scene loads
✓ StartGame() logs correctly
✓ PauseGame() freezes time (press P)
✓ ResumeGame() restores time (press R)
✓ Scene loads work (press N for next scene)

Common Singleton Issues

❌ Common Problems

  • Multiple instances: Check Awake() logic
  • Null reference: Instance accessed before creation
  • Destroyed on load: Missing DontDestroyOnLoad()
  • Wrong instance: Not calling Destroy() on duplicates

✅ Solutions

  • Destroy duplicates: if (_instance != this)
  • Lazy instantiation: Create in getter if null
  • Persist properly: DontDestroyOnLoad(gameObject)
  • Debug logs: Verify Awake() calls
Debug Tip: Add Debug.Log() in Awake() to see when instances are created/destroyed!

Hands-On Implementation 💻

In-Class Challenge (If Time Permits)

Let's implement together:

  1. Create Singleton<T> base class
  2. Create GameManager : Singleton<GameManager>
  3. Add StartGame(), PauseGame(), ResumeGame() methods
  4. Create test script to call methods
  5. Test in Play mode
Note: If we don't finish in class, complete this as homework!

Homework Assignment 📝

Assignment: Singleton Implementation & Testing

Due: Next class
Submission: Video upload to D2L

Requirements:

  1. Implement Singleton<T> generic base class
  2. Implement GameManager using Singleton pattern
  3. Add StartGame(), PauseGame(), ResumeGame() functionality
  4. Create 5 test scenes
  5. Add TestGameManager script to each scene
  6. Record video showing:
    • Playing through all 5 scenes
    • Game Manager persisting
    • Pause/Resume working (P and R keys)
    • Scene transitions (N key)

Recording Your Test Video

Video Requirements

  • Length: 2-5 minutes
  • Show: Unity Editor + Game View
  • Demonstrate: All test cases working
  • Audio: Optional narration explaining what you're testing
  • Format: MP4, MOV, or AVI

Recording Tools

  • Windows: Xbox Game Bar (Win + G), OBS Studio
  • Mac: QuickTime Screen Recording, OBS Studio
  • Linux: SimpleScreenRecorder, OBS Studio
  • Free: All these tools are free!

D2L Submission Instructions

How to Submit

  1. Log in to D2L course shell
  2. Navigate to Assignments → Singleton Pattern Implementation
  3. Upload your video file
  4. In the comments, include:
    • Your name
    • Any issues you encountered
    • What you learned
  5. Submit before deadline
File Size: If your video is too large for D2L, upload to YouTube (unlisted) and submit the link instead.

Grading Rubric (100 points)

Point Breakdown

25 pts: Singleton<T> base class correctly implemented
25 pts: GameManager inherits and uses Singleton properly
15 pts: StartGame(), PauseGame(), ResumeGame() work correctly
15 pts: 5 test scenes created and configured
10 pts: Instance persists across all scenes
10 pts: Video clearly demonstrates all functionality

Additional Resources

📚 Further Reading

  • Baron's Chapter 4: Complete Singleton implementation details
  • Unity Learn: Singleton Tutorial
  • C# Docs: Static classes and members
  • Game Programming Patterns: Singleton Pattern
Office Hours: If you get stuck on the implementation, come see me! Don't wait until the last minute.

Questions & Discussion 💬

Open Floor

Questions about:

  • The patterns roadmap?
  • When to use Singleton vs other patterns?
  • Implementation details?
  • Testing strategy?
  • Homework requirements?
  • Video recording/submission?

Ready to Build! 🚀

Today's Achievements:

Homework Due Next Class:

Singleton implementation + 5-scene test video

Upload to D2L

Your first design pattern implementation awaits! 🎯