// GDnD wiki example // Demonstrates: the game loop owning score and serve state, and subscribing to a ball event // Related pages: [[overview-arcade-classics-as-learning-projects]], [[unity-gamemanager-pattern]], [[observer-pattern]] using UnityEngine; // Minimal match controller: owns the two scores, serves the ball, and re-serves // after each point. This is the smallest version of the central-state ownership // idea that grows into [[unity-gamemanager-pattern]] in later projects. public class PongMatch : MonoBehaviour { [SerializeField] private Ball2D ball; [SerializeField] private int pointsToWin = 11; public int LeftScore { get; private set; } public int RightScore { get; private set; } private void OnEnable() { // Subscribe in OnEnable / unsubscribe in OnDisable to avoid leaks — see [[observer-pattern]]. if (ball != null) { ball.Scored += OnScored; } } private void OnDisable() { if (ball != null) { ball.Scored -= OnScored; } } private void Start() { ServeTowardRandomSide(); } private void OnScored(int direction) { // direction +1 → ball exited right, so the left (player) scores, and vice versa. if (direction > 0) { LeftScore++; } else { RightScore++; } Debug.Log($"Score — Left {LeftScore} : {RightScore} Right"); if (LeftScore >= pointsToWin || RightScore >= pointsToWin) { Debug.Log(LeftScore > RightScore ? "Left player wins!" : "Right player wins!"); LeftScore = 0; RightScore = 0; } // Serve toward the player who just conceded. ball.Serve(direction > 0 ? +1 : -1); } private void ServeTowardRandomSide() { ball.Serve(Random.value < 0.5f ? -1 : +1); } }