The dungeon parameters
- 3-5 total branches going to a boss room respectively. One being a main story boss and the rest being events from a list of possible encounters
- the path is made up of chunks that would have challenge rooms then a rest room all connected by 2-3 halls before each is made.
-The main branch having 3-5 chunks; 2-3 for the other branches
- a minimum of 2-3 chunks from entrance to any events
-the end rooms then having 2-3 challenge rooms without the rest instead of a full chunk
-The halls should interconnect to be more labyrinthine/providing shortcuts
-still having a few leaf parts for merchants or dead ends
Now how do I do this, not a great programmer so after looking around I’m essentially adapting these sources: IEEE Xplore Full-Text PDF: A document on using snap able objects as basis. (pages 4-6) and Bake Your Own 3D Dungeons With Procedural Recipes a much simpler rundown of the ladder.
My trouble is adapting the parameters and code. I have list of halls and rooms but I’m lost on how to connect the next hall piece after instantiating the starter. I’m using empties as connectors, not sure how to find it and keep track of chunks in generation or interconnect/ fill open hallways after. Any suggestions on this or how to adapt the parameters?
At a very high level, when you are creating the rooms, you would created them with “snapping” in mind. Both Unity and and a 3D modelling program, say Blender, have a tool where you move objects in variable increments, like .5m or 1m increments. Then, you will build based off those increments.
Then, when you are procedurally instantiating your buildings, you will have to consider your incremental differences when spawning the next building and spawn them with an offset to the first building, based on their origin point, which again you can change in Unity or Blender.
Another technique you can try is to have binding points on these building, like where the doors are. When you spawn, you match up the door locations, and then face the new addition in the opposite direction and it should be in place.
I, actually am using the door method but I’m not sure how to offset the position, right now creating a number of hallways. Any help on how to find the child of a chosen spawn object to snap them should try a custom component so I can us find component in children?
@rysan007
This is what I have, the red room is the start.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestChunkGenerator : MonoBehaviour
{
// extra end rooms to be placed at the end of each branch // F0 is the first floor there will be diferent list/sets depending on story progress
public List<GameObject> EventSetF0;
// chosen set of floors to be used that will be used in the current generation
private List<GameObject> availableEvents;
// rooms to be used in current gen in addition to an end room; 2-5 in any given generation, the number dropping only if the later added one use rooms are gone
public List<GameObject> selectedEvents;
private int eventRoomSelector;
//one room wil be selected as the main end room/start room temp, later using floor set as above
public List<GameObject> storyRooms;
[SerializeField]
private GameObject currentPin;
private GameObject hallSelector;
private int hallCounter;
//collections of available tiles, this will later reflect the F0 selection above
public List<GameObject> halls;
public List<GameObject> challangeRooms;
public List<GameObject> breakRoom;
void Awake()
{
// *later this will be changed to select EventSet based on story progress.
availableEvents = EventSetF0;
//chooses selectedRooms for generations number of branches and corresponding end rooms
InvokeRepeating("EventSelection", 0f, 0f);
}
void Start()
{
// if there arent any rooms in the scene, make one and add 5-7 halls
if (GameObject.FindGameObjectsWithTag("Room") != null)
{
Instantiate(storyRooms[Random.Range(0, storyRooms.Count)], Vector3.zero, Quaternion.identity);
InvokeRepeating("AddHalls", 0f, 0.2f);
}
else
{
Debug.Log("there is already a room in the scene");
}
}
void Update()
{
}
void EventSelection()
{
//if there arent any avilable events left cancle, otherwise random events are added to the selection until the max of 4
if (availableEvents.Count != -1)
{
if (selectedEvents.Count != 4)
{
eventRoomSelector = Random.Range(0, availableEvents.Count);
selectedEvents.Add(availableEvents[eventRoomSelector]);
availableEvents.Remove(availableEvents[eventRoomSelector]);
}
else
{
CancelInvoke("EventSelection");
}
}
else
{
CancelInvoke("EventSelection");
}
}
void AddHalls()
{
currentPin = GameObject.FindGameObjectWithTag("Pin");
hallSelector = halls[Random.Range(0, halls.Count)];
Instantiate(hallSelector, currentPin.gameObject.transform.position, (currentPin.gameObject.transform.rotation * Quaternion.Euler(0,-1,0)));
currentPin.tag = "Used Pin";
hallCounter++;
if (hallCounter == Random.Range(5, 7))
{
CancelInvoke("AddHalls");
hallCounter = 0;
}
}
}