Advanced Features: Generating Attached Dungeons
Typically, DunGen generates a dungeon based purely on the rules defined in the Dungeon Flow, starting from the world origin. However, you might need to generate a dungeon that physically connects to an existing piece of geometry in your scene.
This is useful for scenarios like:
- Connecting a procedurally generated area (like a mine or cave system) to a static, hand-designed part of your level (like a town entrance).
- Dynamically spawning a new dungeon section attached to a previously generated one.
- Starting generation from a specific, manually placed entrance Tile.
DunGen allows this through the AttachmentSettings property on the DungeonGenerator class. This is configured entirely through code before triggering the generation process.
The AttachmentSettings Class
Before initiating dungeon generation via code, you can create an instance of the DunGen.AttachmentSettings class and assign it to RuntimeDungeon.Generator.AttachmentSettings. This class tells DunGen where and how to attach the start of the new dungeon layout.
There are two primary ways to specify the attachment point:
1. Attaching to a Tile
You can provide a reference to an existing Tile component in your scene. DunGen will then attempt to attach the new dungeon to one of the Doorway components found on that Tile.
- How it works: DunGen randomly selects an available
Doorwayon the targetTile. If the initially chosen doorway is blocked (e.g., by scene geometry or another tile), DunGen will keep trying other available doorways on that sameTileuntil it finds a valid connection point or runs out of options. - Constructor/Usage: You typically instantiate
AttachmentSettingsby passing the targetTilereference: - Use Case: Useful when you want to connect to a specific room or prefab already placed in the scene, but you don't need to dictate the exact doorway used for the connection.
2. Attaching to a Specific Doorway
For more precise control, you can provide a reference directly to a specific Doorway component on an existing Tile.
- How it works: DunGen will attempt to attach the start of the new dungeon only to the specified
Doorway.
Warning
If you provide a specific Doorway, DunGen will not try other doorways on the same tile if the chosen one is blocked or invalid for attachment. It's your responsibility to ensure the provided Doorway is positioned correctly and has clear space for the new dungeon to generate outwards from it. If the connection fails at this specific doorway, the dungeon generation might fail entirely.
- Constructor/Usage: You typically instantiate
AttachmentSettingsby passing the targetDoorwayreference: - Use Case: Ideal when you need the dungeon to connect at a very specific point on an existing tile, like a pre-defined exit archway.
Code Examples
Here are a collection of basic example scripts demonstrating how to set up attached generation. For each example, you would:
- Attach the script to a GameObject in your scene.
- Assign the reference to your
RuntimeDungeoncomponent in the inspector. - Call the
GenerateAttached()method.
Continue from the previous dungeon
In this example, we will generate a new dungeon attached to the last tile on the main path (the Goal) of the previous dungeon that was generated by the RuntimeDungeon component.
public class ContinueDungeon : MonoBehaviour
{
// The dungeon generator to use for generating the new dungeon. Set in inspector
public RuntimeDungeon RuntimeDungeon;
public void GenerateAttached()
{
var previousDungeon = RuntimeDungeon.Generator.CurrentDungeon;
if (previousDungeon != null)
{
var lastTile = previousDungeon.MainPathTiles[previousDungeon.MainPathTiles.Count - 1];
RuntimeDungeon.Generator.AttachmentSettings = new DungeonAttachmentSettings(lastTile);
RuntimeDungeon.Generate();
}
else
Debug.LogError("No previous dungeon found to attach to.");
}
}
Attach to a random Tile from the previous dungeon
In this example, we will generate a new dungeon attached to a random tile of the previous dungeon that was generated by the RuntimeDungeon component.
public class AttachToRandomTile : MonoBehaviour
{
// The dungeon generator to use for generating the new dungeon. Set in inspector
public RuntimeDungeon RuntimeDungeon;
public void GenerateAttached()
{
var previousDungeon = RuntimeDungeon.Generator.CurrentDungeon;
if (previousDungeon != null)
{
// Find all tiles that have unused doorways
var possibleTiles = previousDungeon.AllTiles
.Where(x => x.UnusedDoorways.Any());
if (possibleTiles.Any())
{
// Pick a Tile at random
var chosenTile = possibleTiles.ElementAt(UnityEngine.Random.Range(0, possibleTiles.Count()));
// Generate a new dungeon attached to the chosen tile
RuntimeDungeon.Generator.AttachmentSettings = new DungeonAttachmentSettings(chosenTile);
RuntimeDungeon.Generate();
}
else
Debug.LogError("No tiles with unused doorways found in the previous dungeon.");
}
else
Debug.LogError("No previous dungeon found to attach to.");
}
}
Attach to a specific Doorway
In this example, we generate a new dungeon attached to a specific Doorway component that exists in the scene.
public class AttachToSpecificDoorway : MonoBehaviour
{
// The dungeon generator to use for generating the new dungeon. Set in inspector
public RuntimeDungeon RuntimeDungeon;
// The existing doorway component to attach to. Set in inspector
public Doorway SpecificDoorway;
public void GenerateAttached()
{
RuntimeDungeon.Generator.AttachmentSettings = new DungeonAttachmentSettings(SpecificDoorway);
RuntimeDungeon.Generate();
}
}