| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- using UnityEngine;
- /// <summary>
- /// Main controller for maze generation and management
- /// </summary>
- public class MazeController : MonoBehaviour
- {
- [SerializeField] private MazeConfig mazeConfig = new();
- [SerializeField] private bool generateOnStart = true;
- [SerializeField] private bool visualizeDebug = true;
- [Header("Renderers")]
- [SerializeField] private MazeRenderer mazeRenderer;
- [SerializeField] private MeshMazeRenderer meshMazeRenderer;
- [Header("AI Agents")]
- [SerializeField] private bool spawnAIAgents = true;
- [SerializeField] private AIAgentManager agentManager;
- [Header("Monsters")]
- [SerializeField] private MonsterSpawner monsterSpawner;
- private MazeData currentMaze;
- private MazeGenerator generator;
- void Start()
- {
- if (mazeRenderer == null)
- {
- mazeRenderer = GetComponent<MazeRenderer>() ?? FindAnyObjectByType<MazeRenderer>();
- }
- if (meshMazeRenderer == null)
- {
- meshMazeRenderer = GetComponent<MeshMazeRenderer>() ?? FindAnyObjectByType<MeshMazeRenderer>();
- }
- // Setup Fight Tracker and UI
- InitializeFightTracking();
- // Setup AI agent manager
- if (spawnAIAgents)
- {
- if (agentManager == null)
- {
- agentManager = GetComponent<AIAgentManager>();
- }
- if (agentManager == null)
- {
- // Create agent manager if not already present
- GameObject managerGO = new GameObject("AIAgentManager");
- managerGO.transform.parent = transform;
- agentManager = managerGO.AddComponent<AIAgentManager>();
- }
- }
- // Find MonsterSpawner if not assigned
- if (monsterSpawner == null)
- monsterSpawner = FindAnyObjectByType<MonsterSpawner>();
- if (generateOnStart)
- {
- GenerateMaze();
- }
- }
- /// <summary>
- /// Initializes the fight tracking system and UI
- /// </summary>
- private void InitializeFightTracking()
- {
- // Ensure FightTracker exists
- var fightTracker = FindAnyObjectByType<FightTracker>();
- if (fightTracker == null)
- {
- var trackerGO = new GameObject("FightTracker");
- trackerGO.transform.parent = transform;
- trackerGO.AddComponent<FightTracker>();
- }
- // Ensure ActiveFightsUIPanel exists
- var fightsPanel = FindAnyObjectByType<ActiveFightsUIPanel>();
- if (fightsPanel == null)
- {
- var panelGO = new GameObject("ActiveFightsUIPanel");
- var canvas = FindAnyObjectByType<Canvas>();
- if (canvas != null)
- {
- panelGO.transform.SetParent(canvas.transform);
- }
- else
- {
- panelGO.transform.parent = transform;
- }
- panelGO.AddComponent<ActiveFightsUIPanel>();
- }
- // Ensure SimulationControlsUIPanel exists (pause / 0.5x / 1x / 2x buttons)
- var simControls = FindAnyObjectByType<SimulationControlsUIPanel>();
- if (simControls == null)
- {
- var controlsGO = new GameObject("SimulationControlsUIPanel");
- controlsGO.transform.parent = transform;
- controlsGO.AddComponent<SimulationControlsUIPanel>();
- }
- }
- /// <summary>
- /// Generates a new maze using the current configuration
- /// </summary>
- public void GenerateMaze()
- {
- Debug.Log("Generating maze...");
- generator = new MazeGenerator(mazeConfig);
- currentMaze = generator.Generate();
- if (visualizeDebug)
- {
- VisualizeMaze();
- }
- if (mazeRenderer != null)
- {
- mazeRenderer.RenderMaze();
- }
- if (meshMazeRenderer != null)
- {
- meshMazeRenderer.RefreshMesh();
- }
- // Bake thread-safe maze snapshot for the pathfinding scheduler
- if (PathfindingScheduler.Instance == null)
- {
- var schedulerGO = new GameObject("PathfindingScheduler");
- schedulerGO.transform.parent = transform;
- schedulerGO.AddComponent<PathfindingScheduler>();
- }
- PathfindingScheduler.Instance.BakeMaze(currentMaze);
- // Reset AI agents for new maze
- if (spawnAIAgents && agentManager != null)
- {
- agentManager.ResetForNewMaze();
- }
- // Spawn monsters now that the maze is ready
- if (monsterSpawner != null)
- monsterSpawner.SpawnForMaze(currentMaze, mazeConfig);
- }
- /// <summary>
- /// Visualizes the maze in the editor/game for debugging
- /// </summary>
- private void VisualizeMaze()
- {
- if (currentMaze == null) return;
- // Draw grid visualization in Scene view
- for (int x = 0; x < currentMaze.Width; x += 10)
- {
- Debug.DrawLine(new Vector3(x, 0, 0), new Vector3(x, currentMaze.Height, 0), Color.gray);
- }
- for (int y = 0; y < currentMaze.Height; y += 10)
- {
- Debug.DrawLine(new Vector3(0, y, 0), new Vector3(currentMaze.Width, y, 0), Color.gray);
- }
- // Highlight start and exit points
- foreach (var start in currentMaze.StartPoints)
- {
- Debug.DrawLine(new Vector3(start.x - 0.5f, start.y - 0.5f, 0),
- new Vector3(start.x + 0.5f, start.y + 0.5f, 0), Color.green);
- }
- foreach (var exit in currentMaze.ExitPoints)
- {
- Debug.DrawLine(new Vector3(exit.x - 0.5f, exit.y - 0.5f, 0),
- new Vector3(exit.x + 0.5f, exit.y + 0.5f, 0), Color.red);
- }
- }
- /// <summary>
- /// Gets the current maze data
- /// </summary>
- public MazeData GetCurrentMaze()
- {
- return currentMaze;
- }
- /// <summary>
- /// Sets the current maze data (used by async generators)
- /// </summary>
- public void SetCurrentMaze(MazeData maze)
- {
- currentMaze = maze;
- if (visualizeDebug)
- {
- VisualizeMaze();
- }
- // Render the maze using available renderers
- var renderer = GetComponent<MazeRenderer>();
- if (renderer != null)
- {
- renderer.RenderMaze();
- }
- var meshRenderer = GetComponent<MeshMazeRenderer>();
- if (meshRenderer != null)
- {
- meshRenderer.RefreshMesh();
- }
- // Reset AI agents for new maze
- if (spawnAIAgents && agentManager != null)
- {
- agentManager.ResetForNewMaze();
- }
- // Spawn monsters for the new maze
- if (monsterSpawner != null)
- monsterSpawner.SpawnForMaze(currentMaze, mazeConfig);
- }
- /// <summary>
- /// Gets the current maze configuration
- /// </summary>
- public MazeConfig GetConfig()
- {
- return mazeConfig;
- }
- /// <summary>
- /// Gets a tile at specific coordinates
- /// </summary>
- public MazeTile GetTile(int x, int y)
- {
- return currentMaze?.GetTile(x, y);
- }
- /// <summary>
- /// Checks if a position is walkable
- /// </summary>
- public bool IsWalkable(int x, int y)
- {
- return currentMaze?.IsWalkable(x, y) ?? false;
- }
- /// <summary>
- /// Gets the room at a specific tile position
- /// </summary>
- public MazeRoom GetRoomAtTile(int x, int y)
- {
- return currentMaze?.GetRoomAtTile(x, y);
- }
- /// <summary>
- /// Gets all start points
- /// </summary>
- public System.Collections.Generic.List<Vector2Int> GetStartPoints()
- {
- return currentMaze?.StartPoints ?? new();
- }
- /// <summary>
- /// Gets all exit points
- /// </summary>
- public System.Collections.Generic.List<Vector2Int> GetExitPoints()
- {
- return currentMaze?.ExitPoints ?? new();
- }
- /// <summary>
- /// Gets the AI agent manager
- /// </summary>
- public AIAgentManager GetAgentManager()
- {
- return agentManager;
- }
- void Update()
- {
- // Can be used for real-time generation or maze editing later
- }
- }
|