// GDnD wiki example // Demonstrates: building a grid of objects from a loop, tracking them in a list, and detecting level clearance // Related pages: [[overview-arcade-classics-as-learning-projects]], [[csharp-collections]], [[unity-prefabs-scripting]] using System; using System.Collections.Generic; using UnityEngine; // Spawns the brick wall and owns the "how many bricks are left?" question. The // double loop and the List are the step-2 learning targets: arrays/lists // and level reset. See [[csharp-collections]] and [[unity-prefabs-scripting]]. public class BrickGrid : MonoBehaviour { [Header("Prefab")] [SerializeField] private Brick brickPrefab; [Header("Layout")] [SerializeField] private int columns = 10; [SerializeField] private int rows = 5; [SerializeField] private Vector2 brickSize = new Vector2(1.4f, 0.5f); [SerializeField] private Vector2 spacing = new Vector2(0.1f, 0.1f); [SerializeField] private float topMargin = 1f; // Forwarded brick score, and a one-shot signal when the last brick is cleared. public event Action BrickDestroyed; public event Action LevelCleared; private readonly List activeBricks = new List(); public void BuildLevel() { ClearExistingBricks(); Camera cam = Camera.main; float cellWidth = brickSize.x + spacing.x; float cellHeight = brickSize.y + spacing.y; // Centre the wall horizontally and hang it from just below the top edge. float startX = -((columns - 1) * cellWidth) / 2f; float startY = cam.orthographicSize - topMargin; for (int row = 0; row < rows; row++) { for (int column = 0; column < columns; column++) { Vector3 position = new Vector3( startX + column * cellWidth, startY - row * cellHeight, 0f ); Brick brick = Instantiate(brickPrefab, position, Quaternion.identity, transform); brick.transform.localScale = new Vector3(brickSize.x, brickSize.y, 1f); brick.Destroyed += OnBrickDestroyed; activeBricks.Add(brick); } } } private void OnBrickDestroyed(int score) { BrickDestroyed?.Invoke(score); // Tidy the list, then check for a cleared level. activeBricks.RemoveAll(brick => brick == null); if (activeBricks.Count == 0) { LevelCleared?.Invoke(); } } private void ClearExistingBricks() { foreach (Brick brick in activeBricks) { if (brick != null) { brick.Destroyed -= OnBrickDestroyed; Destroy(brick.gameObject); } } activeBricks.Clear(); } }