/// <summary> /// Creates a new level /// </summary> /// <param name="seed">Level Seed</param> public void CreateNewLevel(int seed = default) { /* * How this works: * The Generate() method will generate the main path recursively. * When the main path is complete, for every created room, it will try * to create a new branch. * When all the positions are in place, tell the branches to spawn the * rooms. */ // Set seed if (seed == default) { seed = Random.Range(int.MinValue, int.MaxValue); } else { Random.InitState(seed); } // Initialize collections _takenLocations = new List <Vector3Int>(); _allRooms = new Dictionary <Vector3Int, Room>(); // Generate Branch mainBranch = new Branch(); _takenLocations.Add(Vector3Int.zero); mainBranch.AddNewRoomPosition(Vector3Int.zero); _exitPlaced = false; Generate(mainBranch, Vector3Int.zero, Forward, 30, 0, true); // Set parents Transform parentTransform = mainBranch.SpawnRooms(_allRooms); parentTransform.name = "Main Branch"; // Open doors for (int i = 0; i < _takenLocations.Count; i++) { _allRooms[_takenLocations[i]] .OpenConnections(); } // Finalize _currentMainBranch = mainBranch; GC.Collect(); }
/// <summary> /// Recursive generator method /// </summary> /// <param name="containingBranch">Branch in which it is contained</param> /// <param name="previousLoc">Previous generated location</param> /// <param name="previousDir">Previous generated direction</param> /// <param name="maxLength">Max branch length</param> /// <param name="count">Amount created</param> /// <param name="canHaveBranch">Can have sub branches</param> private void Generate(Branch containingBranch, Vector3Int previousLoc, Vector3Int previousDir, int maxLength, int count, bool canHaveBranch) { Vector3Int newLoc = previousLoc + previousDir; Vector3Int newDir = previousDir; // Check if it can continue the same direction bool selected = !PositionOccupied(newLoc); // Determine if it should change direction bool changeDir = DirectionChangeRoll || !selected; if (changeDir) { selected = false; ShuffleDirections(); for (int i = 0; i < AllPossibleDirections.Length; i++) { Vector3Int tempLoc = AllPossibleDirections[i] + previousLoc; if (!PositionOccupied(tempLoc)) { newDir = AllPossibleDirections[i]; newLoc = tempLoc; selected = true; break; } } } // If the selection was possible if (selected && count < maxLength) { _takenLocations.Add(newLoc); containingBranch.AddNewRoomPosition(newLoc); Generate(containingBranch, newLoc, newDir, maxLength, count + 1, canHaveBranch); // Try yo place the exit if (!_exitPlaced) { _exitPlaced = true; PlaceExit(newLoc); } // Try to create new branch if (canHaveBranch && HasOpenNeighbor(newLoc) && NewBranchRoll) { Branch subBranch = new Branch(containingBranch); containingBranch.AddNewSubBranch(subBranch); Generate(subBranch, newLoc, newDir, maxLength / 4, 0, false); } } }