WallLayout GetWallLayoutFromObj(GameObject tileObj) { WallLayout layout = WallLayout.O; int wallCount = GetWallCountFromObj(tileObj); if (wallCount == 3) { layout = WallLayout.C; } else if (wallCount == 2) { int wallAngle_1 = Mathf.FloorToInt(tileObj.transform.Find("Wall_1").transform.eulerAngles.y / 90); int wallAngle_2 = Mathf.FloorToInt(tileObj.transform.Find("Wall_2").transform.eulerAngles.y / 90); wallAngle_1 = wallAngle_1 > 180 ? (wallAngle_1 - 180) : wallAngle_1; wallAngle_2 = wallAngle_2 > 180 ? (wallAngle_2 - 180) : wallAngle_2; if (wallAngle_1 == wallAngle_2) { layout = WallLayout.II; } else { layout = WallLayout.L; } } else if (wallCount == 1) { layout = WallLayout.I; } return(layout); }
//======================================= // Functions //======================================= public GameObject GetWallLayoutObj(WallLayout wallLayout) { GameObject[] objList; switch ((int)wallLayout) { default: objList = new GameObject[0]; break; case 0: objList = TileLayoutO; break; case 1: objList = TileLayoutI; break; case 2: objList = TileLayoutL; break; case 3: objList = TileLayoutC; break; case 4: objList = TileLayoutII; break; } Utilities.TryCatchError((objList.Length <= 0), "'TileLayout" + wallLayout + "' has wrong setup in current Maze Setting."); return(objList[Random.Range(0, objList.Length)]); }
// Instead of creating multiple type of wall layout, we rotate existing object to match the wall layout. // This function calculate the rotCount that can be used later to spawn the wall layout. // ex: Quaternion.Euler (0, 90 * rotCount, 0)) int GetLayoutRotationCount(bool[] walls, WallLayout wallLayout) { int count = 0; if (wallLayout == WallLayout.II) { int rnd = Random.Range(0, 2); if (walls [0] == true) { count = 2 * rnd; } else { count = 2 * rnd + 1; } return(count); } for (int i = 0; i < walls.Length; i++) { int wallID = i; bool match = false; for (int j = 0; j < (int)wallLayout; j++) { if (!walls [wallID]) { break; } if (j == ((int)wallLayout - 1)) { match = true; } wallID = wallID + 1 < walls.Length ? (wallID + 1) : (wallID + 1 - walls.Length); } if (match) { count = i; } } return(count); }
// Store wall object in tile class void AssignWallFloorObjToTile(Tile tile, WallLayout wallLayout, int rotCount) { if (wallLayout == WallLayout.O) { return; } // Get wall objects / or assign floor object Dictionary <int, GameObject> wall_obj_list = new Dictionary <int, GameObject>(); foreach (Transform child in tile.transform) { if (child.name.Contains("Wall_")) { int index = int.Parse(child.name.Substring(child.name.IndexOf('_') + 1)) - 1; wall_obj_list.Add(index, child.gameObject); } else if (child.name.Contains("Floor")) { tile.floor_obj = child.gameObject; } } // Assign wall objects to Tile class based on wall layout and rotation int wallID = rotCount; tile.wall_obj [wallID] = wall_obj_list [0]; if (wallLayout == WallLayout.II) { wallID = wallID + 2 < 4 ? (wallID + 2) : (wallID + 2 - 4); tile.wall_obj [wallID] = wall_obj_list [1]; } else { for (int i = 1; i < wall_obj_list.Count; i++) { wallID = wallID + 1 < 4 ? (wallID + 1) : (wallID + 1 - 4); tile.wall_obj [wallID] = wall_obj_list [i]; } } }
bool[] GetWallInfoFromObj(GameObject tileObj, int rotCount) { bool[] wall = new bool[4]; int wallCount = GetWallCountFromObj(tileObj); WallLayout layout = GetWallLayoutFromObj(tileObj); if (layout == WallLayout.II) { wall[rotCount] = true; rotCount = rotCount + 2 < 4 ? (rotCount + 2) : (rotCount + 2 - 4); wall[rotCount] = true; } else { for (int i = 0; i < wallCount; i++) { wall[rotCount] = true; rotCount = rotCount + 1 < 4 ? (rotCount + 1) : (rotCount + 1 - 4); } } return(wall); }
// Generate maze using custom game object Maze GenerateMaze_Custom() { // Init object list for the custom maze InitCustomMazeObjList(); int width = 0; int length = 0; foreach (GameObject obj in customTileObjList) { // Gather tile data from preset tile object int X = GetObjX(obj); width = width > (X + 1) ? width : (X + 1); int Z = GetObjZ(obj); length = length > (Z + 1) ? length : (Z + 1); } level.mazeWidth = width; level.mazeLength = length; Maze maze = new Maze(level.mazeWidth, level.mazeLength); // Spawn and init each preset tile from the custom maze object GameObject mazeObj = new GameObject() { name = "Maze" }; foreach (GameObject obj in customTileObjList) { // Gather tile data from preset tile object int X = GetObjX(obj); int Z = GetObjZ(obj); int rotCount = Mathf.FloorToInt(obj.transform.eulerAngles.y / 90); rotCount = rotCount < 4 ? rotCount : (rotCount - 4); WallLayout wallLayout = GetWallLayoutFromObj(obj); bool[] wall = GetWallInfoFromObj(obj, rotCount); // Spawn tile object GameObject tileObj = GameObject.Instantiate(obj, new Vector3(X * 10, -0, Z * 10), Quaternion.Euler(0, 90 * rotCount, 0)); tileObj.name = "Tile [" + X + "]" + "[" + Z + "] " + "(" + wallLayout + ")"; tileObj.AddComponent <Tile>(); // Generate Tile class data Tile tile = tileObj.GetComponent <Tile>(); tile.X = X; tile.Z = Z; tile.wall = wall; tile.wallLayout = wallLayout; AssignWallFloorObjToTile(tile, wallLayout, rotCount); // Group tile tile.transform.parent = mazeObj.transform; maze.mazeTile[X, Z] = tile; } for (int i = 0; i < level.mazeWidth; i++) { for (int j = 0; j < level.mazeLength; j++) { maze.mazeTileList.Add(maze.mazeTile[i, j]); } } return(maze); }
// Get tiles with desired wall layout from input list public static List <Tile> UpdateTileListWithDesiredWallLayout(List <Tile> oldList, WallLayout desiredWallLayout) { List <Tile> newList = new List <Tile>(); foreach (Tile t in oldList) { if (t.wallLayout == desiredWallLayout) { newList.Add(t); } } Utilities.TryCatchError((newList.Count <= 0), "There is no such wall layout in the input list."); return(newList); }