Advanced Features: Custom Post-Processing Steps
DunGen's generation process involves several stages: creating the main path, adding branches, placing props, handling the lock & key system, etc. Sometimes, you need to inject your own custom logic during this process, specifically after the main dungeon layout (Dungeon data structure) exists but before generation is fully marked as complete.
This is useful for:
- Integrating third-party systems (like pathfinding baking or custom culling setups) that need the final level geometry.
- Running complex analysis or modification routines on the generated
Dungeondata. - Implementing custom prop placement logic that depends on the overall dungeon structure.
- Performing tasks that need to happen after DunGen's built-in post-processing (like lock/key placement) but before the final
GenerationStatus.Completeevent fires.
DunGen offers two ways to add your custom post-processing logic:
- Registering Steps via Code: Use the
RegisterPostProcessStepmethod on theDungeonGeneratorfor fine-grained control. - Creating Custom Adapters: Derive a component from
BaseAdapterfor a more component-based approach, often used for integrations.
Method 1: Registering Steps via Code (RegisterPostProcessStep)
This method allows you to dynamically register a C# method to be called during the post-processing phase.
How it Works:
- Get a reference to your
DungeonGeneratorinstance. - Call the
generator.RegisterPostProcessStep()method, providing your callback method and configuration options. - DunGen will execute your callback method at the appropriate time during its post-processing phase.
The Method Signature:
void RegisterPostProcessStep(Action<DungeonGenerator> postProcessCallback, int priority, PostProcessPhase phase);
Action<DungeonGenerator> postProcessCallback: This is your custom method (or lambda expression) that will be executed. It receives theDungeonGeneratorinstance as an argument, allowing you to access the generated dungeon data viagenerator.CurrentDungeon.int priority: Determines the execution order within a specific phase. Higher priority numbers execute first. Steps with the same priority have an undefined execution order relative to each other. DunGen's built-in steps (like lock/key placement) also have priorities.PostProcessPhase phase: An enum specifying when your step should run relative to DunGen's internal post-processing:PostProcessPhase.BeforeBuiltIn: Your step runs before DunGen handles its standard post-processing (Locks, Keys, Props, etc).PostProcessPhase.AfterBuiltIn: Your step runs after DunGen handles its standard post-processing.
Example:
public class MyCustomPostProcessor : MonoBehaviour
{
// Assign your Runtime Dungeon component in the inspector
public RuntimeDungeon RuntimeDungeon;
private void Start()
{
if (RuntimeDungeon == null)
return;
// Register our custom method to run AFTER DunGen's built-in steps, with priority 0
RuntimeDungeon.Generator.RegisterPostProcessStep(MyCustomPostProcessLogic, 0, PostProcessPhase.AfterBuiltIn);
}
private void OnDestroy()
{
if (RuntimeDungeon == null)
return;
// Unregister our custom method
RuntimeDungeon.Generator.UnregisterPostProcessStep(MyCustomPostProcessLogic);
}
// This is the method that gets called by DunGen
private void MyCustomPostProcessLogic(DungeonGenerator generator)
{
Debug.Log("Running custom post-process step!");
// Access the generated dungeon data
Dungeon dungeon = generator.CurrentDungeon;
// Perform your custom logic here
Debug.Log($"Dungeon has {dungeon.AllTiles.Count} tiles.");
}
}
Use Cases: Ideal for one-off post-processing tasks defined in specific scripts, or when you need precise control over execution order relative to DunGen's built-in steps.
Method 2: Creating Custom Adapters (BaseAdapter)
This approach is more component-oriented and is the standard way DunGen integrates systems like Pathfinding and Culling. You create a new script that inherits from DunGen.Adapters.BaseAdapter.
How it Works:
- Create a new C# script.
- Make it inherit from
DunGen.Adapters.BaseAdapter. - Override the abstract
Run(DungeonGenerator generator)method. This is where your custom logic goes. - Attach this new component script to the same GameObject that has the
RuntimeDungeoncomponent. - DunGen will automatically find all
BaseAdaptercomponents on that GameObject and execute theirRunmethods during the post-processing phase.
Adapter Properties:
Priority(Inspector Field): Inherited fromBaseAdapter. This integer value controls the execution order of all post-processing steps within the same phase. Higher priority adapters run first.
Execution Phase
Adapters derived from BaseAdapter run after DunGen's built-in post-processing steps, similar to PostProcessPhase.AfterBuiltIn.
Example:
using UnityEngine;
using DunGen;
using DunGen.Adapters;
// Attach this component to the same GameObject as RuntimeDungeon
public class MyCustomAdapter : BaseAdapter
{
protected override void Run(DungeonGenerator generator)
{
Debug.Log($"Running MyCustomAdapter (Priority: {Priority})");
Dungeon dungeon = generator.CurrentDungeon;
if (dungeon == null)
{
Debug.LogError("Dungeon data is null in custom adapter!", this);
return;
}
// --- Add custom logic here ---
Debug.Log($"Adapter processing dungeon with {dungeon.AllTiles.Count} tiles.");
// Example: Find all objects with a specific tag and activate them
// foreach(var tile in dungeon.AllTiles) { ... }
}
}
Use Cases: Excellent for creating reusable integration components (like the built-in pathfinding/culling adapters), especially when the logic might need configuration via Inspector fields on the component itself. Easier to manage as self-contained units.
Choosing the Right Method
RegisterPostProcessStep:- Use when you need very fine control over execution order relative to DunGen's internal steps (
BeforeBuiltInvs.AfterBuiltIn). - Use when the logic is part of a script that isn't naturally attached to the
RuntimeDungeonGameObject. - Use when you need to dynamically add/remove steps based on runtime conditions.
- Use when you need very fine control over execution order relative to DunGen's internal steps (
BaseAdapter:- Use for creating self-contained, reusable integration components (preferred for integrations like pathfinding, culling, etc.).
- Use when you want to configure the step via the Inspector (add public fields to your adapter).
- Generally simpler setup if you just need logic to run after the main generation and built-in steps. Ordering is primarily relative to other adapters.
Custom post-processing provides a vital hook for tailoring the generated dungeon and integrating it fully with your game systems.