| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- using UnityEngine;
- using System.Collections;
- using System.Threading.Tasks;
- /// <summary>
- /// Generates mazes asynchronously to prevent blocking the main thread
- /// Useful for very large mazes that take time to generate
- /// </summary>
- public class AsyncMazeGenerator : MonoBehaviour
- {
- [Header("Generation Settings")]
- [SerializeField] private MazeController mazeController;
- [SerializeField] private bool generateOnStart = false;
- [Header("Progress")]
- [SerializeField] private UnityEngine.UI.Slider progressBar;
- [SerializeField] private TMPro.TextMeshProUGUI progressText;
- private bool isGenerating = false;
- private MazeData currentMaze;
- private int progressCompletedTiles = 0;
- private int progressTotalTiles = 0;
- private string progressMessage = "";
- private readonly object progressLock = new object();
- private int lastLoggedPercent = -1;
- void Start()
- {
- if (generateOnStart)
- {
- GenerateMazeAsync();
- }
- }
- /// <summary>
- /// Starts asynchronous maze generation
- /// </summary>
- public void GenerateMazeAsync()
- {
- if (isGenerating)
- {
- Debug.LogWarning("Maze generation already in progress");
- return;
- }
- StartCoroutine(GenerateMazeCoroutine());
- }
- /// <summary>
- /// Coroutine that handles the async generation
- /// </summary>
- private IEnumerator GenerateMazeCoroutine()
- {
- isGenerating = true;
- UpdateProgress(0f, "Initializing...");
- // Get config
- var config = mazeController.GetConfig();
- if (config == null)
- {
- Debug.LogError("No maze config found");
- isGenerating = false;
- yield break;
- }
- // Create generator with progress callback
- var generator = new MazeGenerator(config, OnProgressUpdate);
- // Generate in background thread
- Task<MazeData> generationTask = Task.Run(() => generator.Generate());
- while (!generationTask.IsCompleted)
- {
- int completed;
- int total;
- string message;
- lock (progressLock)
- {
- completed = progressCompletedTiles;
- total = progressTotalTiles;
- message = progressMessage;
- }
- float progress = total > 0 ? completed / (float)total : 0f;
- UpdateProgress(progress, $"Generating maze... {completed}/{total} ({(int)(progress * 100)}%) {message}");
- int percent = Mathf.Clamp((int)(progress * 100), 0, 100);
- if (percent != lastLoggedPercent)
- {
- Debug.Log($"Maze progress: {completed}/{total} tiles ({percent}%) - {message}");
- lastLoggedPercent = percent;
- }
- yield return new WaitForSeconds(0.1f);
- }
- if (generationTask.IsFaulted)
- {
- Debug.LogError($"Maze generation failed: {generationTask.Exception}");
- isGenerating = false;
- yield break;
- }
- currentMaze = generationTask.Result;
- mazeController.SetCurrentMaze(currentMaze);
- UpdateProgress(1f, "Complete!");
- yield return new WaitForSeconds(0.5f); // Show completion briefly
- UpdateProgress(0f, "Ready");
- isGenerating = false;
- Debug.Log($"Async maze generation complete: {currentMaze.Width}x{currentMaze.Height}");
- }
- /// <summary>
- /// Updates progress UI
- /// </summary>
- private void UpdateProgress(float progress, string message)
- {
- if (progressBar != null)
- {
- progressBar.value = progress;
- }
- if (progressText != null)
- {
- progressText.text = message;
- }
- }
- private void OnProgressUpdate(int completedTiles, int totalTiles, string message)
- {
- lock (progressLock)
- {
- progressCompletedTiles = completedTiles;
- progressTotalTiles = totalTiles;
- progressMessage = message;
- }
- }
- /// <summary>
- /// Checks if generation is in progress
- /// </summary>
- public bool IsGenerating()
- {
- return isGenerating;
- }
- /// <summary>
- /// Gets the most recently generated maze
- /// </summary>
- public MazeData GetCurrentMaze()
- {
- return currentMaze;
- }
- }
|