MazeSceneBuilder.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. namespace MazeGen
  4. {
  5. /// <summary>
  6. /// Single entry point for milestone 1: drop this on one empty GameObject in the scene
  7. /// and press Play. It creates the generator, agent and path visualizer, spawns the
  8. /// start room(s), and lets you click yellow exit markers to walk the agent through them.
  9. /// </summary>
  10. [RequireComponent(typeof(MazeGenerator))]
  11. public class MazeSceneBuilder : MonoBehaviour
  12. {
  13. [SerializeField, Min(1)] private int startRoomCount = 1;
  14. [SerializeField] private float startRoomSpread = 6f;
  15. private MazeGenerator _generator;
  16. private MazeAgentController _agentController;
  17. private PathVisualizer _pathVisualizer;
  18. private MazeCameraController _cameraController;
  19. private readonly Dictionary<int, ExitMarker> _exitMarkers = new Dictionary<int, ExitMarker>();
  20. private void Awake()
  21. {
  22. _generator = GetComponent<MazeGenerator>();
  23. _generator.RoomGenerated += OnRoomGenerated;
  24. _generator.ExitAdded += OnExitAdded;
  25. var agentGO = new GameObject("Agent");
  26. agentGO.transform.SetParent(transform, false);
  27. _agentController = agentGO.AddComponent<MazeAgentController>();
  28. _agentController.Initialize(_generator);
  29. var pathGO = new GameObject("PathVisualizer");
  30. pathGO.transform.SetParent(transform, false);
  31. pathGO.AddComponent<LineRenderer>();
  32. _pathVisualizer = pathGO.AddComponent<PathVisualizer>();
  33. var cam = Camera.main;
  34. if (cam != null)
  35. {
  36. _cameraController = cam.GetComponent<MazeCameraController>();
  37. if (_cameraController == null)
  38. _cameraController = cam.gameObject.AddComponent<MazeCameraController>();
  39. }
  40. }
  41. private void Start()
  42. {
  43. Room firstStartRoom = null;
  44. for (int i = 0; i < startRoomCount; i++)
  45. {
  46. float angle = startRoomCount > 1 ? (360f / startRoomCount) * i : 0f;
  47. Vector2 pos = startRoomCount > 1
  48. ? new Vector2(Mathf.Cos(angle * Mathf.Deg2Rad), Mathf.Sin(angle * Mathf.Deg2Rad)) * startRoomSpread
  49. : Vector2.zero;
  50. var room = _generator.GenerateStartRoom(pos);
  51. firstStartRoom ??= room;
  52. }
  53. // Milestone 1: single agent spawns in the first start room.
  54. _agentController.Spawn(firstStartRoom);
  55. _agentController.Agent.RoomEntered += room => _pathVisualizer.AppendPoint(room.Position);
  56. _agentController.Agent.RoomEntered += room => _cameraController?.FocusOn(room.Position);
  57. _agentController.Agent.ReachedExitRoom += room => Debug.Log($"[MazeGen] Agent reached the exit room (id {room.Id})!");
  58. _pathVisualizer.AppendPoint(firstStartRoom.Position);
  59. _cameraController?.SnapTo(firstStartRoom.Position);
  60. RefreshMarkerVisuals();
  61. }
  62. private void OnRoomGenerated(Room room)
  63. {
  64. var roomGO = new GameObject($"Room_{room.Id}_{room.Kind}");
  65. roomGO.transform.SetParent(transform, false);
  66. roomGO.AddComponent<RoomView>().Initialize(room);
  67. foreach (var exit in room.Exits)
  68. SpawnExitMarker(room, exit);
  69. }
  70. private void OnExitAdded(Room room, Exit exit)
  71. {
  72. SpawnExitMarker(room, exit);
  73. RefreshMarkerVisuals();
  74. }
  75. private void SpawnExitMarker(Room room, Exit exit)
  76. {
  77. var markerGO = new GameObject($"Exit_{exit.Id}");
  78. markerGO.transform.SetParent(transform, false);
  79. var marker = markerGO.AddComponent<ExitMarker>();
  80. marker.Initialize(room, exit);
  81. _exitMarkers[exit.Id] = marker;
  82. }
  83. private void Update()
  84. {
  85. if (!MazeInput.WasLeftClickedThisFrame()) return;
  86. Camera cam = Camera.main;
  87. if (cam == null) return;
  88. Ray ray = cam.ScreenPointToRay(MazeInput.GetPointerScreenPosition());
  89. RaycastHit2D hit = Physics2D.GetRayIntersection(ray, Mathf.Infinity);
  90. if (hit.collider != null && hit.collider.TryGetComponent(out ExitMarker marker))
  91. OnExitClicked(marker.ExitData);
  92. }
  93. private void OnExitClicked(Exit exit)
  94. {
  95. if (_agentController.Agent == null || exit.OwnerRoomId != _agentController.Agent.CurrentRoom.Id)
  96. {
  97. Debug.Log("[MazeGen] That exit isn't reachable from your current room.");
  98. return;
  99. }
  100. if (_agentController.TryUseExit(exit))
  101. RefreshMarkerVisuals();
  102. }
  103. private void RefreshMarkerVisuals()
  104. {
  105. Room currentRoom = _agentController.Agent?.CurrentRoom;
  106. MazeAgent agent = _agentController.Agent;
  107. foreach (var marker in _exitMarkers.Values)
  108. marker.UpdateVisual(currentRoom, agent);
  109. }
  110. }
  111. }