/// <summary> /// Places tiles down at rooms that are children of roomParent, walls that are children of wallParent, and stairs at the /// position of stairsTrans. Also randomly places dinosaur bones in the rooms. /// </summary> /// <param name="roomParent">The parent of all the rooms (position and size)</param> /// <param name="wallParent">The parent of all the walls (position)</param> /// <param name="stairsTrans">Transform of the stairs (position)</param> /// <returns>Returns the newly created Tilemap</returns> public Tilemap SpawnTileMap(Transform roomParent, Transform wallParent, Transform stairsTrans) { // Initialize the list of potential positions to spawn the one-tiled decor List <Vector2Int> oneTiledDecor = new List <Vector2Int>(); // Initialize the list of potential position to spawn the two-tiled decor List <Vector2Int> twoTiledDecor = new List <Vector2Int>(); // Create the tilemap GameObject tileMapObj = Instantiate(_tileMapPrefab, new Vector3(-0.5f, -0.5f, 0), Quaternion.identity); tileMapObj.name = "Grid"; _tileMapRef = tileMapObj.transform.GetChild(0).GetComponent <Tilemap>(); if (_tileMapRef == null) { Debug.Log("There is no Tilemap attached to the child of " + tileMapObj.name); } // Clear any tiles on the map _tileMapRef.ClearAllTiles(); // Add floor tiles to the rooms // Iterate over each room foreach (Transform curRoom in roomParent) { Vector2Int topLeft = new Vector2Int(Mathf.RoundToInt(curRoom.position.x - (curRoom.localScale.x - 1) / 2f), Mathf.RoundToInt(curRoom.position.y + (curRoom.localScale.y - 1) / 2f)); int amRows = Mathf.RoundToInt(curRoom.localScale.y); int amCols = Mathf.RoundToInt(curRoom.localScale.x); // Iterate over the rows of the room for (int curRow = 0; curRow < amRows; ++curRow) { // Iterate over the columns of the room for (int curCol = 0; curCol < amCols; ++curCol) { // Choose a random floor tile int randomIndex = Random.Range(0, _tileSet.SingleFloorTilesLength()); // Calculate the current location Vector2Int curLocation = topLeft + new Vector2Int(curCol, -curRow); // Give a chance for this tile to be convered in single-tiled decor // Only if there are any single-tiled decorations if (_tileSet.SingleTiledDecorationTilesLength() > 0 && Random.Range(0, _singleTileDecorationChance) == 0) { oneTiledDecor.Add(curLocation); } // Give a chance for this tile to be covered in a two-tiled decor // Only if there are any double-tiled decorations else if (_tileSet.TwoTiledDecorationTilesLength() > 0 && Random.Range(0, _twoTileDecorationChance) == 0) { twoTiledDecor.Add(curLocation); } // Add a single room tile at the current location AddTile(curLocation, _tileSet.GetSingleFloorTile(randomIndex)); } } } // Add walls // Iterate over the walls foreach (Transform curWall in wallParent) { // The type of wall the current wall is // If (-1, 0) - wall is left; (0, -1) - wall is close // (1, 0) - wall is right; (0, 1) - wall is far // (-1, -1) - wall is closeLeftOuterCorner; (1, -1) - wall is closeRightOuterCorner // (-1, 1) - wall is farLeftOuterCorner; (1, 1) - wall is farRightOuterCorner Vector2Int curWallTypeVect = Vector2Int.zero; Vector2Int innerWallTypeVect = Vector2Int.zero; // Determine what time of tile this is by looking at its neighbors BoundsInt aroundBounds = new BoundsInt(-1, -1, 0, 3, 3, 1); foreach (Vector3Int curPos in aroundBounds.allPositionsWithin) { // If its the position of the current tile if (curPos.x == 0 && curPos.y == 0) { continue; } // Get the tile on the tile map at that locaiton Vector3Int curWallPos = new Vector3Int(Mathf.RoundToInt(curWall.position.x), Mathf.RoundToInt(curWall.position.y), 0); Sprite curTileSpr = _tileMapRef.GetSprite(curPos + curWallPos); // Test if the sprite exists, if it doesn't we can determine somethings about this wall if (curTileSpr == null) { // These should be called max once per iteration, since a wall will never have both left and right empty // or both close and far tiles empty if (curPos.x != 0 && curPos.y == 0) { curWallTypeVect.x = curPos.x; } else if (curPos.y != 0 && curPos.x == 0) { curWallTypeVect.y = curPos.y; } // If, its neither, then it may be an inner wall, so save the current position else { innerWallTypeVect.x = curPos.x; innerWallTypeVect.y = curPos.y; } } } // If the wall is a left wall if (curWallTypeVect.x == -1 && curWallTypeVect.y == 0) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.LeftWallTilesLength()); AddTile(curWall.position, _tileSet.GetLeftWallTile(randomIndex)); } // If the wall is a right wall else if (curWallTypeVect.x == 1 && curWallTypeVect.y == 0) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.RightWallTilesLength()); AddTile(curWall.position, _tileSet.GetRightWallTile(randomIndex)); } // If the wall is a close wall else if (curWallTypeVect.x == 0 && curWallTypeVect.y == -1) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.CloseWallTilesLength()); AddTile(curWall.position, _tileSet.GetCloseWallTile(randomIndex)); } // If the wall is a far wall else if (curWallTypeVect.x == 0 && curWallTypeVect.y == 1) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.FarWallTilesLength()); AddTile(curWall.position, _tileSet.GetFarWallTile(randomIndex)); } // Outer corners // If the wall is a close left outer corner else if (curWallTypeVect.x == -1 && curWallTypeVect.y == -1) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.CloseLeftOuterCornerWallTilesLength()); AddTile(curWall.position, _tileSet.GetCloseLeftOuterCornerWallTile(randomIndex)); } // If the wall is a close right outer corner else if (curWallTypeVect.x == 1 && curWallTypeVect.y == -1) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.CloseRightOuterCornerWallTilesLength()); AddTile(curWall.position, _tileSet.GetCloseRightOuterCornerWallTile(randomIndex)); } // If the wall is a far left outer corner else if (curWallTypeVect.x == -1 && curWallTypeVect.y == 1) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.FarLeftOuterCornerWallTilesLength()); AddTile(curWall.position, _tileSet.GetFarLeftOuterCornerWallTile(randomIndex)); } // If the wall is a far right outer corner else if (curWallTypeVect.x == 1 && curWallTypeVect.y == 1) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.FarRightOuterCornerWallTilesLength()); AddTile(curWall.position, _tileSet.GetFarRightOuterCornerWallTile(randomIndex)); } // Inner corners // If the wall is a close left inner corner else if (innerWallTypeVect.x == -1 && innerWallTypeVect.y == -1) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.CloseLeftInnerCornerWallTilesLength()); AddTile(curWall.position, _tileSet.GetCloseLeftInnerCornerWallTile(randomIndex)); } // If the wall is a close right inner corner else if (innerWallTypeVect.x == 1 && innerWallTypeVect.y == -1) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.CloseRightInnerCornerWallTilesLength()); AddTile(curWall.position, _tileSet.GetCloseRightInnerCornerWallTile(randomIndex)); } // If the wall is a far left inner corner else if (innerWallTypeVect.x == -1 && innerWallTypeVect.y == 1) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.FarLeftInnerCornerWallTilesLength()); AddTile(curWall.position, _tileSet.GetFarLeftInnerCornerWallTile(randomIndex)); } // If the wall is a far right inner corner else if (innerWallTypeVect.x == 1 && innerWallTypeVect.y == 1) { // Choose a random tile int randomIndex = Random.Range(0, _tileSet.FarRightInnerCornerWallTilesLength()); AddTile(curWall.position, _tileSet.GetFarRightInnerCornerWallTile(randomIndex)); } // If the wall is a completely different kind of tile else { Debug.Log("Strange wall encountered CurWallTypeVect: " + curWallTypeVect + ". InnerWallTypeVect: " + innerWallTypeVect); AddTile(curWall.position, _tileSet.GetSingleFloorTile(0)); } } // Add the stairs to the tilemap // Choose a random tile int randomStairIndex = Random.Range(0, _tileSet.StairTilesLength()); AddTile(stairsTrans.position, _tileSet.GetStairTile(randomStairIndex)); // Iterate over the tiles we said we would spawn single-tiled decor at and try to spawn some foreach (Vector2Int tilePos in oneTiledDecor) { AttemptPlaceSingleTileDecoration(tilePos); } // Iterate over the tiles we said we would spawn two-tiled decor at and try to spawn some foreach (Vector2Int tilePos in twoTiledDecor) { AttemptPlaceTwoTileDecoration(tilePos); } // Give the tilemap return(_tileMapRef); }