Advanced Features: Lock & Key System
DunGen includes a robust system for procedurally placing locked doors and their corresponding keys within your dungeon layouts. This allows you to create progression gates, control access to specific areas (like boss rooms), and add another layer of dynamic gameplay.
Implementing the Lock & Key system involves configuration across several assets and requires some C# scripting to integrate the key pickup and door unlocking logic into your actual game mechanics.
The Core Components:
- Key Manager Asset: Defines the different types of keys available in your dungeon.
- Tile Set Asset: Specifies which prefabs to use for locked doors.
- Dungeon Flow Asset: Determines where locks and keys should be placed within the dungeon structure.
- Runtime Interfaces (
IKeySpawner,IKeyLock): C# interfaces you implement to tell DunGen how to spawn key objects and notify your prefabs when they are assigned a specific key type.
1. Creating the Key Manager
First, you need to define the types of keys your dungeon can use.
- Create a Key Manager asset: Right-click in Project view >
Create > DunGen > Key Manager. - Select the asset. In the Inspector, click "Add New Key" for each distinct key type you need (e.g., Red Key, Blue Key, Boss Key).
- Configure each Key Type:
- Name: A human-readable name (e.g., "Red Skeleton Key"). Used for identification, potentially in UI.
- Prefab: (Optional) A prefab representing the key visually in the scene (e.g., a collectible key model). DunGen will tell your code which prefab to potentially spawn via the
IKeySpawnerinterface. - Colour: (Optional) A color used for visual debugging in the editor and potentially for color-coding locks and keys in your game via the
IKeyLockinterface.
Note
These properties (Prefab, Colour) are conveniences. Whether you use them depends entirely on how you implement the runtime interfaces later.
- Link to Dungeon Flow: You must assign this Key Manager asset to the
Key Managerfield in your Dungeon Flow asset so DunGen knows which keys are available for that flow.
2. Assigning a Locked Door Prefab
Next, tell DunGen which prefab(s) represent a locked door. This is done per Tile Set.
- Select a Tile Set asset that contains tiles where locked doors might appear.
- In the Inspector, find the "Locked Door Prefabs" section.
- Click "Add" to create an entry for a specific Doorway Socket. Choose the relevant socket from the dropdown (e.g., "Default").
- This means when a lock is placed on a connection using this socket type, and involving a tile from this Tile Set, DunGen will look here for the prefab to use.
- Within that socket entry, click "Add New Prefab" and drag your locked door prefab(s) into the slot(s).
- Configure Weights if you add multiple locked door prefabs for the same socket type. The weights determine the likelihood of each prefab being chosen when that type of locked door is needed.
3. Placing Keys and Locks (Dungeon Flow)
Now, define where in the dungeon structure keys and locks should appear. This is configured in the Dungeon Flow editor.
- Select your Dungeon Flow asset and click "Open Flow Editor".
- Select a Node or a Line Segment in the graph.
- In the Inspector, you'll find
KeysandLockslists.
Assigning Keys/Locks:
- Click "Add" under the
KeysorLockslist. - Select the desired Key Type (defined in your Key Manager) from the dropdown.
Placement Differences:
- Nodes: Keys/Locks assigned here will be placed specifically within the single tile generated by that node.
- Line Segments: Keys/Locks assigned here will be placed randomly somewhere along the sequence of tiles generated by that line segment.
Node-Specific Setting: Lock Placement
- When assigning a Lock to a Node, you get an extra
Lock Placementoption:Entrance: The locked door will only be placed on the doorway the player enters the node's tile through. Essential for boss rooms or requiring a key found earlier to enter a specific tile.Exit: The locked door will only be placed on the doorway used to exit the node's tile.Any: The locked door can be placed on any doorway connected to the node's tile.
Line Segment Setting: Lock Count
- When assigning a Lock to a Line Segment, you can specify a
Count(Min/Max) for how many instances of that lock type should appear within that segment.
Solvability Guarantee
DunGen's logic ensures dungeons are always completable regarding locks and keys:
- It places Locks first based on your Flow configuration.
- It then determines where the corresponding Keys must be placed.
- It guarantees that keys are placed in locations accessible before their corresponding locks are encountered along the main path. It uses the potential key locations you assigned in the Flow Editor to find valid spots.
4. Tying it into our Game (Runtime Integration)
DunGen handles the placement logic, but it needs your C# code to handle the game-specific actions of spawning key objects and reacting to lock/key assignments. This is done by implementing two interfaces:
IKeySpawner Interface
- Purpose: Implement this interface on a component to tell DunGen how and where a key object should actually appear in the game.
- Method:
void SpawnKey(KeySpawnParameters keySpawnParameters); - Workflow:
- When DunGen decides a specific
Keyneeds to be placed at a location defined in the Dungeon Flow (Node or Line Segment). - It searches for GameObjects at valid positions within the target Tile(s).
- It finds components on those GameObjects that implement
IKeySpawner. - It randomly selects one of these components.
- It calls the
SpawnKeymethod on the selected component, passing information about the specificKeytype.
- When DunGen decides a specific
-
Implementation Examples:
- Spawn Prefab: Your
SpawnKeymethod could instantiate thekey.Prefabat the component's position (like the demo scene'sKeySpawnPointscript). - Add to Inventory: Your
SpawnKeymethod on an enemy's script could add thekeyto that enemy's drop loot table. - Place in Chest: Your
SpawnKeymethod on a chest script could add thekeyto the chest's contents.
KeySpawnPoint.csusing UnityEngine; using DunGen; using DunGen.LockAndKey; public class KeySpawnPoint : MonoBehaviour, IKeySpawner { // Check if the key has already been spawned public bool HasSpawnedKey => spawnedKey != null; private GameObject spawnedKey; public bool CanSpawnKey(KeyManager keyManager, Key key) { // We can't spawn a key if one has already been spawned if (HasSpawnedKey) return false; // We can't spawn a key if it has no prefab return key.Prefab != null; } public void SpawnKey(KeySpawnParameters keySpawnParameters) { var key = keySpawnParameters.Key; if (keySpawnParameters.Key.Prefab == null) { Debug.LogWarning($"Key '{key.Name}' needs to be spawned here, but has no Prefab assigned in the Key Manager.", this); return; } // Instantiate the key prefab defined in the Key Manager spawnedKey = Instantiate(key.Prefab, transform.position, transform.rotation); // Notify the DunGen about any IKeyLock components that were created var keyLockComponents = spawnedKey.GetComponentsInChildren<IKeyLock>(); keySpawnParameters.OutputSpawnedKeys.AddRange(keyLockComponents); } } - Spawn Prefab: Your
Props & Keys Timing
Props (Local, Random, Global) are processed before the Lock & Key system runs. This means if you have a chest placed as a random prop, DunGen can correctly identify it later as a potential spawn location for a key if the chest's script implements IKeySpawner.
IKeyLock Interface
- Purpose: Implement this interface on components within your Locked Door prefabs and your Key prefabs to be notified which specific Key type has been assigned to them.
- Method:
void OnKeyAssigned(Key key, KeyManager manager); - Workflow:
- When DunGen places a locked door prefab, it calls
OnKeyAssignedon all components implementingIKeyLockwithin that prefab's hierarchy, passing the assignedKey. - When DunGen tells your
IKeySpawnerto spawn a key and you (optionally) return a list of spawnedIKeyLockback to DunGen.OnKeyAssignedwill be called automatically on all of these components.
- When DunGen places a locked door prefab, it calls
-
Implementation Examples:
- Visual Feedback: Change the color of a mesh renderer on the lock/key based on
key.Colour(like the demo scene'sKeyColourscript). - Store Key Info: Store the required
Keyobject on the locked door script so you know what key the player needs when they interact with it. - Initialize Key Object: Set up properties on the collectible key script based on the assigned
Keytype.
KeyColour.csusing UnityEngine; using DunGen; public class KeyColour : MonoBehaviour, IKeyLock { // Assign in Inspector public Renderer TargetRenderer; // Used to change material properties without leaking material instances into the scene private MaterialPropertyBlock propertyBlock; public void OnKeyAssigned(Key key, KeyManager manager) { if (TargetRenderer != null) { if(propertyBlock == null) propertyBlock = new MaterialPropertyBlock(); // Use the color defined in the Key Manager propertyBlock.SetColor("_Color", key.Colour); TargetRenderer.SetPropertyBlock(propertyBlock); } } } - Visual Feedback: Change the color of a mesh renderer on the lock/key based on
By combining asset configuration with these runtime interfaces, you can create complex and solvable lock and key puzzles within your procedurally generated DunGen levels. Remember that the actual player interaction logic (detecting key pickup, checking inventory, triggering door unlocks) needs to be implemented in your own game systems.