//For implementation I decided to start the generation at 0,0 and then expand on the x and y /// <summary> /// Generate Binary Space Partioning grid for the base of dungeon generation. /// </summary> /// <param name="dungeonSize">Overall size to generate the dungeon in.</param> /// <param name="maxBSPIterations">Amount of times to iterate over dungeon generation algorithm.</param> /// <param name="minRoomSize">Minium room size to allow in the generation.</param> private void GenerateDungeon(Vector2Int dungeonSize, int maxBSPIterations, Vector2Int minRoomSize) { //Setup first node and node list nodeList = new List <Node>(); roomList = new List <RoomNode>(); RoomNode rootNode = new RoomNode(new Vector2Int(0, 0), dungeonSize, null); nodeList.Add(rootNode); roomList.Add(rootNode); for (int i = 0; i < maxIterations; i++) { //Declare nodes and variables to be assigned RoomNode nodeOne; RoomNode nodeTwo; Vector2Int nodeTwoPos; Vector2Int nodeOneSize; Vector2Int nodeTwoSize; //Choose wether to split on x or y axis //TODO: Refactor and make less janky CutType cutType; if (rootNode.Size.x > rootNode.Size.y) { cutType = CutType.x; } else if (rootNode.Size.x < rootNode.Size.y) { cutType = CutType.y; } else { cutType = (CutType)UnityEngine.Random.Range((int)CutType.x, (int)(CutType.y)); } //TODO: Fix issues with higher iterations causing smaller than minium size rooms //Potential fix, if node size too small, skip current cut if (cutType == CutType.x) { //Choose a random postion between the current root nodes position and size to split and set the child nodes within int cutPosX = UnityEngine.Random.Range(minRoomSize.x, rootNode.Size.x - minRoomSize.x); //Calculate the cut and the size of the new room nodeOneSize = new Vector2Int(cutPosX, rootNode.Size.y); nodeTwoSize = new Vector2Int(rootNode.Size.x - cutPosX, rootNode.Size.y); nodeTwoPos = new Vector2Int(rootNode.Position.x + nodeOneSize.x, rootNode.Position.y); nodeOne = new RoomNode(rootNode.Position, nodeOneSize, rootNode); nodeTwo = new RoomNode(nodeTwoPos, nodeTwoSize, rootNode); } else { //Choose a random postion between the current root nodes position and size to split and set the child nodes within int cutPosY = UnityEngine.Random.Range(minRoomSize.y, rootNode.Size.y - minRoomSize.y); //Calculate the size and postion of the new rooms nodeOneSize = new Vector2Int(rootNode.Size.x, cutPosY); nodeTwoSize = new Vector2Int(rootNode.Size.x, rootNode.Size.y - cutPosY); nodeTwoPos = new Vector2Int(rootNode.Position.x, rootNode.Position.y + nodeOneSize.y); nodeOne = new RoomNode(rootNode.Position, nodeOneSize, rootNode); nodeTwo = new RoomNode(nodeTwoPos, nodeTwoSize, rootNode); } //Add new rooms as children to the root then move on to the next root node nodeList.Add(nodeOne); nodeList.Add(nodeTwo); rootNode.AddChild(nodeOne); rootNode.AddChild(nodeTwo); nodeOne.ParentNode = rootNode; nodeTwo.ParentNode = rootNode; roomList.Add(nodeOne); roomList.Add(nodeTwo); rootNode.Visited = true; roomList.Remove(rootNode); //Set new root node rootNode = roomList[0]; } }