IEnumerator GenerateDungeonAsync() { yield return(null); startTime = Time.realtimeSinceStartup; if (maxRoomPlaceAttempts < minRoomCount) { maxRoomPlaceAttempts = minRoomCount; } #region Clear existing tiles if (tiles != null) { for (int x = 0; x < tiles.GetLength(0); x++) { for (int y = 0; y < tiles.GetLength(1); y++) { Destroy(tiles[x, y].gameObject); } } } #endregion #region Generate new tiles with default values tiles = new Tile[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { tiles[x, y] = Instantiate(tilePrefab, this.transform); tiles[x, y].gameObject.name = string.Format("Tile({0}, {1})", x, y); tiles[x, y].x = x; tiles[x, y].y = y; tiles[x, y].parentArray = tiles; } } #endregion #region Generate dungeon rooms rooms = new List <DungeonRoom>(); // If min and max are swapped, swap them back if (minRoomSize > maxRoomSize) { int t = minRoomSize; minRoomSize = maxRoomSize; maxRoomSize = t; } #region Create random amount of rooms DungeonRoom temp; int targetRoomCount = Random.Range(minRoomCount, maxRoomCount + 1); for (int r = 0; r < maxRoomPlaceAttempts; r++) { temp = DungeonRoom.GenerateNewRoom(minRoomSize, maxRoomSize, width, height); if (rooms.Count > 0) { bool overlap = false; for (int i = 0; i < rooms.Count; i++) { overlap |= DungeonRoom.OverlapCheck(rooms[i], temp); } if (overlap) { continue; } } // Mark room tiles as such for (int x = temp.left; x <= temp.right; x++) { for (int y = temp.bottom; y <= temp.top; y++) { tiles[x, y].availability = TileAvailability.Room; } } rooms.Add(temp); if (rooms.Count >= targetRoomCount) { break; } } #endregion foreach (DungeonRoom room in rooms) { yield return(StartCoroutine(SetupRoomTiles(room))); } #endregion #region Generate corridors using recursive backtracker, making sure to fill any islands for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (tiles[x, y].availability == TileAvailability.Empty) { yield return(StartCoroutine(RecursiveCorridorGenerator(x, y))); } } } #endregion #region Mark all dead ends deadEnds = new List <Vector2Int>(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { switch (tiles[x, y].corridors) { case Directions.North: case Directions.East: case Directions.South: case Directions.West: deadEnds.Add(new Vector2Int(x, y)); break; } } } #endregion #region Use regresion to eliminate some of the dead ends #endregion #region Make entrances into rooms #endregion lastDungeonTime = Time.realtimeSinceStartup - startTime; timeText.text = string.Format("Dungeon generated in {0:F3} seconds.", lastDungeonTime); dungeonCompleteCallback?.Invoke(); isRunning = false; }
public static bool OverlapCheck(DungeonRoom d1, DungeonRoom d2) { return(((d1.right >= d2.left) && (d1.left <= d2.right)) && ((d1.top >= d2.bottom) && (d1.bottom <= d2.top))); }