// GDnD wiki example // Demonstrates: the game loop owning score and lives, level reset on clear, and game over on no lives // Related pages: [[overview-arcade-classics-as-learning-projects]], [[unity-gamemanager-pattern]], [[observer-pattern]] using UnityEngine; // Central controller: owns score and lives, builds each level, serves the ball, // and responds to the two events that drive Breakout — a brick destroyed and a // level cleared. This is the step-2 version of [[unity-gamemanager-pattern]]. public class BreakoutGame : MonoBehaviour { [SerializeField] private Ball2D ball; [SerializeField] private BrickGrid grid; [SerializeField] private int startingLives = 3; public int Score { get; private set; } public int Lives { get; private set; } private void OnEnable() { ball.Missed += OnBallMissed; grid.BrickDestroyed += OnBrickDestroyed; grid.LevelCleared += OnLevelCleared; } private void OnDisable() { ball.Missed -= OnBallMissed; grid.BrickDestroyed -= OnBrickDestroyed; grid.LevelCleared -= OnLevelCleared; } private void Start() { StartGame(); } private void StartGame() { Score = 0; Lives = startingLives; grid.BuildLevel(); ball.Serve(); } private void OnBrickDestroyed(int value) { Score += value; Debug.Log($"Score: {Score}"); } private void OnBallMissed() { Lives--; Debug.Log($"Ball lost. Lives remaining: {Lives}"); if (Lives > 0) { ball.Serve(); } else { Debug.Log($"Game over. Final score: {Score}"); StartGame(); } } private void OnLevelCleared() { Debug.Log("Level cleared!"); grid.BuildLevel(); ball.Serve(); } }