IEnumerator RenderDungeon() { tiles.DisableAll(); for (int x = 0; x < dungeonWidth; x++) { for (int y = 0; y < dungeonHeight; y++) { if (dungeon[x, y] == 2) { dungeon[x, y] = 0; } if (dungeon[x, y] == 1) { ObjectPool.PooledObject tile = tiles.GetObjectFromPool; tile.SetActive(true); tile.scale = Vector3.one; tile.position = new Vector3( x - (dungeonWidth / 2) + (tile.scale.x / 2), y - (dungeonHeight / 2) + (tile.scale.y / 2) ); } } yield return(null); } }
IEnumerator GenerateDungeon() { if (dungeonHeight % 2 == 0) { throw new System.FormatException("dungeonHeight should be an odd number"); } if (dungeonWidth % 2 == 0) { throw new System.FormatException("roomMaxDimension should be an odd number"); } if (roomMinDimension % 2 == 0) { throw new System.FormatException("roomMinDimension should be an odd number"); } if (roomMaxDimension % 2 == 0) { throw new System.FormatException("roomMaxDimension should be an odd number"); } if (tileSize % 2 == 0) { throw new System.FormatException("tileSize should be an odd number"); } isGenerating = true; retryCount = 0; dungeonRect = Rect.zero; dungeonRect.height = dungeonHeight - 2; // minus 2 to give a 1 unit edge padding around the whole dungeon dungeonRect.width = dungeonWidth - 2; // minus 2 to give a 1 unit edge padding around the whole dungeon dungeonRect.center = transform.position; if (tiles != null) { tiles.ClearPool(); } Camera.main.orthographicSize = Mathf.Max(dungeonWidth / 2, dungeonHeight / 2) + 2; dungeon = new IntGrid(dungeonWidth, dungeonHeight); tiles = new ObjectPool(roomPrefab, dungeonWidth * dungeonHeight, false, false, transform); // make retryAttempts attempts to place rooms randomly within the dungeon while (retryCount < retryAttempts) { Vector2 randomPosition = new Vector2(ClampValueToOddNumber(Random.Range(0, dungeonWidth) - dungeonWidth / 2f), ClampValueToOddNumber(Random.Range(0, dungeonHeight) - dungeonHeight / 2f)); Vector2 randomScale = new Vector2(ClampValueToOddNumber(Random.Range(roomMinDimension, roomMaxDimension)), ClampValueToOddNumber(Random.Range(roomMinDimension, roomMaxDimension))); Collider2D overlapBox = Physics2D.OverlapBox(randomPosition, randomScale + (Vector2.one * minDistanceBetweenRooms * 2), 0f); if (overlapBox == null && IsRoomInBounds(randomPosition, randomScale)) { ObjectPool.PooledObject room = tiles.GetObjectFromPool; room.SetActive(true); room.position = randomPosition; room.scale = randomScale; yield return(new WaitForSeconds(0.1f)); } else { retryCount++; } } // carve out the rooms from the array of cells and disable the rooms in the pool foreach (KeyValuePair <string, ObjectPool.PooledObject> entry in tiles.GetObjectPool) { if (entry.Value.activeInHierarchy) { Vector3 roomPositionOffset = new Vector3(dungeonWidth / 2f, dungeonHeight / 2f); GameObject room = entry.Value.gameObject; Vector3 scale = room.transform.localScale; for (float x = -scale.x / 2; x <= scale.x / 2; x++) { for (float y = -scale.y / 2; y <= scale.y / 2; y++) { Point point = new Point((int)x, (int)y) + room.transform.position + roomPositionOffset; dungeon[point.x, point.y] = 2; } } tiles.Disable(entry.Key); yield return(null); } } // generate the maze in the empty space of the dungeon dungeon = new Maze(dungeon, true).mazeGrid; yield return(StartCoroutine(RenderDungeon())); yield return(StartCoroutine(StartFloodFill())); yield return(StartCoroutine(RenderDungeon())); yield return(StartCoroutine(RemoveDeadEnds())); yield return(StartCoroutine(RenderDungeon())); isGenerating = false; }