Skip to content

Line Segment Injection

The following example script demonstrates how to procedurally add tile injection rules, allowing us to inject tiles onto specific line segments in the dungeon flow.

using DunGen;
using System;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Injects tiles into the dungeon based on the line segment inside the dungeon flow. 0 is the first line segment in the dungeon flow
/// </summary>
public class TileSegmentInjector : MonoBehaviour
{
    [Serializable]
    public class LineSegmentInjectedTileSet
    {
        /// <summary>
        /// Which line segment does this rule apply to? 0 is the first line segment in the dungeon flow
        /// </summary>
        public int LineSegmentIndex = 0;
        /// <summary>
        /// The tile set to inject
        /// </summary>
        public TileSet TileSet = null;
        /// <summary>
        /// If required, DunGen will retry generating the dungeon until this tile is successfully injected
        /// </summary>
        public bool Required = true;
    }

    /// <summary>
    /// The runtime dungeon to inject tiles into
    /// </summary>
    public RuntimeDungeon RuntimeDungeon = null;
    /// <summary>
    /// Padding as a percentage of the line segment, to prevent injected tiles from appearing too close to the start or end of the segment
    /// </summary>
    [Range(0f, 25f)]
    public float PaddingPercentage = 0.0f;
    /// <summary>
    /// A list of injection rules
    /// </summary>
    public List<LineSegmentInjectedTileSet> InjectionRules = new List<LineSegmentInjectedTileSet>();


    private void OnEnable()
    {
        if(RuntimeDungeon == null)
            RuntimeDungeon = FindObjectOfType<RuntimeDungeon>();

        if(RuntimeDungeon != null)
            RuntimeDungeon.Generator.TileInjectionMethods += InjectTiles;
    }

    private void OnDisable()
    {
        if (RuntimeDungeon != null)
            RuntimeDungeon.Generator.TileInjectionMethods -= InjectTiles;
    }

    private void InjectTiles(RandomStream randomStream, ref List<InjectedTile> tilesToInject)
    {
        var generator = RuntimeDungeon.Generator;
        var dungeonFlow = generator.DungeonFlow;

        float normalizedPaddingPercentage = PaddingPercentage / 100.0f;
        float normalizedLengthSoFar = 0.0f;

        for (int i = 0; i < dungeonFlow.Lines.Count; i++)
        {
            float min = normalizedLengthSoFar;
            float max = normalizedLengthSoFar + dungeonFlow.Lines[i].Length;
            float length = max - min;

            var rule = InjectionRules.Find(x => x.LineSegmentIndex == i);

            if(rule != null)
            {
                float normalizedPathDepth = Mathf.Lerp(min + normalizedPaddingPercentage, max - normalizedPaddingPercentage, (float)randomStream.NextDouble());
                tilesToInject.Add(new InjectedTile(rule.TileSet, true, normalizedPathDepth, 0.0f, rule.Required));
            }

            normalizedLengthSoFar = max;
        }
    }
}