2 - 1
This commit is contained in:
5
.idea/.idea.BABA_YAGA/.idea/workspace.xml
generated
5
.idea/.idea.BABA_YAGA/.idea/workspace.xml
generated
@@ -12,10 +12,7 @@
|
|||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="d308d1cb-09fc-4331-ba20-00f7b43d1576" name="Changes" comment="">
|
<list default="true" id="d308d1cb-09fc-4331-ba20-00f7b43d1576" name="Changes" comment="">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Prefabs/Environment/Hall/End.prefab" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Prefabs/Environment/Hall/End.prefab" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkSpawner.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkSpawner.cs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Presets/MazeRework.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Presets/MazeRework.asset" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Scenes/Main Scene.unity" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scenes/Main Scene.unity" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkGenerator.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkGenerator.cs" afterDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,37 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Sirenix.OdinInspector;
|
||||||
|
|
||||||
namespace Baba_yaga.GameSetup.MazeRework.Animation
|
namespace Baba_yaga.GameSetup.MazeRework.Animation
|
||||||
{
|
{
|
||||||
|
public enum RenderSweepStyle
|
||||||
|
{
|
||||||
|
RowByRow,
|
||||||
|
CenterOut,
|
||||||
|
RandomPop
|
||||||
|
}
|
||||||
|
|
||||||
public class MazeAnimator : MonoBehaviour
|
public class MazeAnimator : MonoBehaviour
|
||||||
{
|
{
|
||||||
[Header("Animation Settings")]
|
[FoldoutGroup("Algorithm Animation")]
|
||||||
[Tooltip("How many cell changes to process in a single frame (if stepDelay is 0).")]
|
[Tooltip("How many cell changes to process in a single frame (if stepDelay is 0).")]
|
||||||
[Min(1)]
|
[MinValue(1)]
|
||||||
public int cellsPerFrame = 1; // Default to 1 so you can see it clearly!
|
public int cellsPerFrame = 1; // Default to 1 so you can see it clearly!
|
||||||
|
|
||||||
|
[FoldoutGroup("Algorithm Animation")]
|
||||||
[Tooltip("Delay in seconds between every single cell change. Set to > 0 to actually see the checking flashes!")]
|
[Tooltip("Delay in seconds between every single cell change. Set to > 0 to actually see the checking flashes!")]
|
||||||
public float stepDelay = 0.05f;
|
public float stepDelay = 0.05f;
|
||||||
|
|
||||||
|
[FoldoutGroup("Algorithm Animation")]
|
||||||
[Tooltip("Extra delay (in seconds) between major generation phases (like switching from Rooms to Carving).")]
|
[Tooltip("Extra delay (in seconds) between major generation phases (like switching from Rooms to Carving).")]
|
||||||
public float delayBetweenPhases = 0.5f;
|
public float delayBetweenPhases = 0.5f;
|
||||||
|
|
||||||
|
[FoldoutGroup("3D Render Phase")]
|
||||||
|
[Tooltip("How the final 3D prefabs pop into existence.")]
|
||||||
|
[EnumToggleButtons]
|
||||||
|
public RenderSweepStyle renderSweepStyle = RenderSweepStyle.CenterOut;
|
||||||
|
|
||||||
private Coroutine _animationRoutine;
|
private Coroutine _animationRoutine;
|
||||||
|
|
||||||
public void AnimateGeneration(
|
public void AnimateGeneration(
|
||||||
@@ -33,6 +48,8 @@ namespace Baba_yaga.GameSetup.MazeRework.Animation
|
|||||||
_animationRoutine = StartCoroutine(AnimateRoutine(history, grid, spawner, yOffset, container, onComplete));
|
_animationRoutine = StartCoroutine(AnimateRoutine(history, grid, spawner, yOffset, container, onComplete));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[FoldoutGroup("Debug Actions")]
|
||||||
|
[Button("Stop Animation", ButtonSizes.Medium), GUIColor(1f, 0.4f, 0.4f)]
|
||||||
public void StopAnimation()
|
public void StopAnimation()
|
||||||
{
|
{
|
||||||
if (_animationRoutine != null)
|
if (_animationRoutine != null)
|
||||||
@@ -122,37 +139,60 @@ namespace Baba_yaga.GameSetup.MazeRework.Animation
|
|||||||
// --- Phase 2: Render 3D Map ---
|
// --- Phase 2: Render 3D Map ---
|
||||||
spawner.isPreviewMode = false;
|
spawner.isPreviewMode = false;
|
||||||
|
|
||||||
// Sweep across the grid and spawn the heavy 3D modular pieces
|
List<Vector2Int> renderQueue = new List<Vector2Int>();
|
||||||
for (int z = 0; z < depth; z++)
|
for (int z = 0; z < depth; z++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < width; x++)
|
for (int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
|
renderQueue.Add(new Vector2Int(x, z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderSweepStyle == RenderSweepStyle.CenterOut)
|
||||||
|
{
|
||||||
|
Vector2 center = new Vector2(width / 2f, depth / 2f);
|
||||||
|
renderQueue.Sort((a, b) => Vector2.Distance(center, a).CompareTo(Vector2.Distance(center, b)));
|
||||||
|
}
|
||||||
|
else if (renderSweepStyle == RenderSweepStyle.RandomPop)
|
||||||
|
{
|
||||||
|
System.Random rng = new System.Random();
|
||||||
|
for (int i = 0; i < renderQueue.Count; i++)
|
||||||
|
{
|
||||||
|
int rand = rng.Next(i, renderQueue.Count);
|
||||||
|
var temp = renderQueue[i];
|
||||||
|
renderQueue[i] = renderQueue[rand];
|
||||||
|
renderQueue[rand] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sweep across the grid and spawn the heavy 3D modular pieces
|
||||||
|
foreach (var pt in renderQueue)
|
||||||
|
{
|
||||||
|
int x = pt.x;
|
||||||
|
int z = pt.y;
|
||||||
|
|
||||||
workingGrid[x, z] = finalGrid[x, z];
|
workingGrid[x, z] = finalGrid[x, z];
|
||||||
workingHighlights[x, z] = MazeCellHighlight.None;
|
workingHighlights[x, z] = MazeCellHighlight.None;
|
||||||
|
|
||||||
// Only yield when we actually spawn a piece to create a cool sweep wave!
|
|
||||||
if (finalGrid[x, z] != MazeReworkCellType.Wall)
|
if (finalGrid[x, z] != MazeReworkCellType.Wall)
|
||||||
{
|
{
|
||||||
// 1. Flash an Evaluating highlight to visualize "choosing" this cell
|
|
||||||
spawner.FlashHighlight(MazeCellHighlight.EvaluatingValid, x, z, yOffset, container);
|
spawner.FlashHighlight(MazeCellHighlight.EvaluatingValid, x, z, yOffset, container);
|
||||||
|
|
||||||
if (stepDelay > 0f)
|
if (stepDelay > 0f)
|
||||||
{
|
{
|
||||||
yield return new WaitForSeconds(stepDelay * 0.5f); // Short pause for the check
|
yield return new WaitForSeconds(stepDelay * 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Spawn the actual piece
|
|
||||||
spawner.RefreshCell(workingGrid, workingHighlights, x, z, yOffset, container);
|
spawner.RefreshCell(workingGrid, workingHighlights, x, z, yOffset, container);
|
||||||
|
|
||||||
// Wait a tiny fraction of a second to create the sweeping wave effect
|
|
||||||
if (stepDelay > 0f)
|
if (stepDelay > 0f)
|
||||||
{
|
{
|
||||||
yield return new WaitForSeconds(stepDelay * 0.5f); // faster than the algorithm checks
|
yield return new WaitForSeconds(stepDelay * 0.5f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
processedThisFrame++;
|
processedThisFrame++;
|
||||||
if (processedThisFrame >= cellsPerFrame * 2) // Twice as fast as algorithm phase
|
if (processedThisFrame >= cellsPerFrame * 2)
|
||||||
{
|
{
|
||||||
yield return null;
|
yield return null;
|
||||||
processedThisFrame = 0;
|
processedThisFrame = 0;
|
||||||
@@ -161,11 +201,9 @@ namespace Baba_yaga.GameSetup.MazeRework.Animation
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Even if it's a wall, refresh it to clear the preview walls (if any)
|
|
||||||
spawner.RefreshCell(workingGrid, workingHighlights, x, z, yOffset, container);
|
spawner.RefreshCell(workingGrid, workingHighlights, x, z, yOffset, container);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_animationRoutine = null;
|
_animationRoutine = null;
|
||||||
onComplete?.Invoke();
|
onComplete?.Invoke();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Sirenix.OdinInspector;
|
||||||
using Baba_yaga.GameSetup.MazeRework.Algorithms;
|
using Baba_yaga.GameSetup.MazeRework.Algorithms;
|
||||||
|
|
||||||
namespace Baba_yaga.GameSetup.MazeRework
|
namespace Baba_yaga.GameSetup.MazeRework
|
||||||
@@ -20,51 +21,63 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
[CreateAssetMenu(fileName = "MazeReworkConfig", menuName = "BABA_YAGA/MazeRework/Config")]
|
[CreateAssetMenu(fileName = "MazeReworkConfig", menuName = "BABA_YAGA/MazeRework/Config")]
|
||||||
public class MazeReworkConfig : ScriptableObject
|
public class MazeReworkConfig : ScriptableObject
|
||||||
{
|
{
|
||||||
[Header("Algorithm")]
|
[FoldoutGroup("Algorithm")]
|
||||||
[Tooltip("Which carving algorithm to use for generating the maze corridors.")]
|
[Tooltip("Which carving algorithm to use for generating the maze corridors.")]
|
||||||
|
[EnumToggleButtons]
|
||||||
public MazeAlgorithmType algorithm = MazeAlgorithmType.DFSRecursive;
|
public MazeAlgorithmType algorithm = MazeAlgorithmType.DFSRecursive;
|
||||||
|
|
||||||
[Header("Grid Dimensions")]
|
[FoldoutGroup("Grid Dimensions")]
|
||||||
[Tooltip("Width of the maze grid. Best if odd to align with wall-corridor-wall patterning.")]
|
[Tooltip("Width of the maze grid. Best if odd to align with wall-corridor-wall patterning.")]
|
||||||
[Min(5)]
|
[MinValue(5)]
|
||||||
public int width = 21;
|
public int width = 21;
|
||||||
|
|
||||||
|
[FoldoutGroup("Grid Dimensions")]
|
||||||
[Tooltip("Depth of the maze grid. Best if odd to align with wall-corridor-wall patterning.")]
|
[Tooltip("Depth of the maze grid. Best if odd to align with wall-corridor-wall patterning.")]
|
||||||
[Min(5)]
|
[MinValue(5)]
|
||||||
public int depth = 21;
|
public int depth = 21;
|
||||||
|
|
||||||
[Header("Seeding")]
|
[FoldoutGroup("Seeding")]
|
||||||
[Tooltip("If true, a random seed will be generated at runtime.")]
|
[Tooltip("If true, a random seed will be generated at runtime.")]
|
||||||
public bool useRandomSeed = true;
|
public bool useRandomSeed = true;
|
||||||
|
|
||||||
|
[FoldoutGroup("Seeding")]
|
||||||
[Tooltip("Seed used when useRandomSeed is false.")]
|
[Tooltip("Seed used when useRandomSeed is false.")]
|
||||||
|
[HideIf("useRandomSeed")]
|
||||||
public int seed = 1337;
|
public int seed = 1337;
|
||||||
|
|
||||||
[Header("Starting Location")]
|
[FoldoutGroup("Starting Location")]
|
||||||
[Tooltip("Starting coordinates for the generator (usually odd numbers like 1, 1).")]
|
[Tooltip("Starting coordinates for the generator (usually odd numbers like 1, 1).")]
|
||||||
public Vector2Int startLocation = new Vector2Int(1, 1);
|
public Vector2Int startLocation = new Vector2Int(1, 1);
|
||||||
|
|
||||||
[Header("Rooms Configuration")]
|
[FoldoutGroup("Rooms Configuration")]
|
||||||
[Tooltip("Whether to place open rooms in the maze before generating corridors.")]
|
[Tooltip("Whether to place open rooms in the maze before generating corridors.")]
|
||||||
public bool generateRooms = true;
|
public bool generateRooms = true;
|
||||||
|
|
||||||
|
[FoldoutGroup("Rooms Configuration")]
|
||||||
[Tooltip("Number of rooms to attempt to generate.")]
|
[Tooltip("Number of rooms to attempt to generate.")]
|
||||||
[Min(0)]
|
[ShowIf("generateRooms")]
|
||||||
|
[MinValue(0)]
|
||||||
public int roomCount = 3;
|
public int roomCount = 3;
|
||||||
|
|
||||||
|
[FoldoutGroup("Rooms Configuration")]
|
||||||
[Tooltip("Minimum room size (width and height).")]
|
[Tooltip("Minimum room size (width and height).")]
|
||||||
|
[ShowIf("generateRooms")]
|
||||||
public Vector2Int minRoomSize = new Vector2Int(3, 3);
|
public Vector2Int minRoomSize = new Vector2Int(3, 3);
|
||||||
|
|
||||||
|
[FoldoutGroup("Rooms Configuration")]
|
||||||
[Tooltip("Maximum room size (width and height).")]
|
[Tooltip("Maximum room size (width and height).")]
|
||||||
|
[ShowIf("generateRooms")]
|
||||||
public Vector2Int maxRoomSize = new Vector2Int(5, 5);
|
public Vector2Int maxRoomSize = new Vector2Int(5, 5);
|
||||||
|
|
||||||
[Header("Maze Density & Loops")]
|
[FoldoutGroup("Maze Density & Loops")]
|
||||||
[Tooltip("Probability (0 to 1) of carving extra doors for rooms to allow multiple entry points.")]
|
[Tooltip("Probability (0 to 1) of carving extra doors for rooms to allow multiple entry points.")]
|
||||||
[Range(0f, 1f)]
|
[ShowIf("generateRooms")]
|
||||||
|
[PropertyRange(0f, 1f)]
|
||||||
public float extraRoomDoorChance = 0.3f;
|
public float extraRoomDoorChance = 0.3f;
|
||||||
|
|
||||||
|
[FoldoutGroup("Maze Density & Loops")]
|
||||||
[Tooltip("Probability (0 to 1) of removing dead-ends or carving random extra walls to introduce loops/alternative paths.")]
|
[Tooltip("Probability (0 to 1) of removing dead-ends or carving random extra walls to introduce loops/alternative paths.")]
|
||||||
[Range(0f, 1f)]
|
[PropertyRange(0f, 1f)]
|
||||||
public float loopChance = 0.1f;
|
public float loopChance = 0.1f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,28 +12,39 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MazeReworkManager : MonoBehaviour
|
public class MazeReworkManager : MonoBehaviour
|
||||||
{
|
{
|
||||||
[Header("Configuration")]
|
[FoldoutGroup("Setup")]
|
||||||
|
[Required]
|
||||||
[SerializeField] private MazeReworkConfig config;
|
[SerializeField] private MazeReworkConfig config;
|
||||||
|
|
||||||
[Header("References")]
|
[FoldoutGroup("Setup")]
|
||||||
|
[Required]
|
||||||
[SerializeField] private MazeReworkSpawner spawner;
|
[SerializeField] private MazeReworkSpawner spawner;
|
||||||
|
|
||||||
|
[FoldoutGroup("Setup")]
|
||||||
|
[Required]
|
||||||
[SerializeField] private Transform mazeContainer;
|
[SerializeField] private Transform mazeContainer;
|
||||||
|
|
||||||
|
[FoldoutGroup("Setup")]
|
||||||
[SerializeField] private MazeAnimator animator;
|
[SerializeField] private MazeAnimator animator;
|
||||||
|
|
||||||
[Header("Animation")]
|
[FoldoutGroup("Animation")]
|
||||||
[Tooltip("If true, visually animates the generation process step-by-step. (Best used with 1 floor)")]
|
[Tooltip("If true, visually animates the generation process step-by-step. (Best used with 1 floor)")]
|
||||||
[SerializeField] private bool animateGeneration = false;
|
[SerializeField] private bool animateGeneration = false;
|
||||||
|
|
||||||
[Header("Multi-floor Settings")]
|
[FoldoutGroup("Multi-floor Settings")]
|
||||||
[Tooltip("Number of floors to generate.")]
|
[Tooltip("Number of floors to generate.")]
|
||||||
[Min(1)]
|
[MinValue(1)]
|
||||||
[SerializeField] private int floorCount = 1;
|
[SerializeField] private int floorCount = 1;
|
||||||
|
|
||||||
|
[FoldoutGroup("Multi-floor Settings")]
|
||||||
[Tooltip("Physical height difference between adjacent floors.")]
|
[Tooltip("Physical height difference between adjacent floors.")]
|
||||||
|
[ShowIf("@floorCount > 1")]
|
||||||
[SerializeField] private float floorHeight = 4.0f;
|
[SerializeField] private float floorHeight = 4.0f;
|
||||||
|
|
||||||
|
[FoldoutGroup("Multi-floor Settings")]
|
||||||
[Tooltip("Number of staircase connections to generate between adjacent floors.")]
|
[Tooltip("Number of staircase connections to generate between adjacent floors.")]
|
||||||
[Min(0)]
|
[ShowIf("@floorCount > 1")]
|
||||||
|
[MinValue(0)]
|
||||||
[SerializeField] private int connectionsPerFloor = 2;
|
[SerializeField] private int connectionsPerFloor = 2;
|
||||||
|
|
||||||
private List<MazeReworkCellType[,]> _grids = new List<MazeReworkCellType[,]>();
|
private List<MazeReworkCellType[,]> _grids = new List<MazeReworkCellType[,]>();
|
||||||
@@ -85,9 +96,9 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates the maze grid data using the rework generator and initializes the spawner.
|
/// Generates the maze grid data using the rework generator and initializes the spawner.
|
||||||
|
/// Clears existing maze and generates a new one.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Button("Generate Maze", ButtonSizes.Large)]
|
[Button("Generate Maze", ButtonSizes.Large)]
|
||||||
[ContextMenu("Generate Maze")]
|
|
||||||
public void GenerateAndSpawn()
|
public void GenerateAndSpawn()
|
||||||
{
|
{
|
||||||
if (config == null)
|
if (config == null)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Sirenix.OdinInspector;
|
||||||
using Baba_yaga.GameSetup.MazeRework.Animation;
|
using Baba_yaga.GameSetup.MazeRework.Animation;
|
||||||
|
|
||||||
namespace Baba_yaga.GameSetup.MazeRework
|
namespace Baba_yaga.GameSetup.MazeRework
|
||||||
@@ -10,63 +11,129 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MazeReworkSpawner : MonoBehaviour
|
public class MazeReworkSpawner : MonoBehaviour
|
||||||
{
|
{
|
||||||
[Header("Modular Hallway Prefabs")]
|
[FoldoutGroup("Modular Hallway Prefabs")]
|
||||||
|
[FoldoutGroup("Modular Hallway Prefabs/Hall 'I' (Straight)")]
|
||||||
[Tooltip("Prefab for Hall 'I' (Straight connection - opposite paths).")]
|
[Tooltip("Prefab for Hall 'I' (Straight connection - opposite paths).")]
|
||||||
|
[AssetsOnly]
|
||||||
public GameObject hallPrefab;
|
public GameObject hallPrefab;
|
||||||
|
[FoldoutGroup("Modular Hallway Prefabs/Hall 'I' (Straight)")]
|
||||||
|
[AssetsOnly]
|
||||||
|
public GameObject[] hallPrefabs;
|
||||||
|
|
||||||
|
[FoldoutGroup("Modular Hallway Prefabs/HallDoubleRoom '+' (Crossroad)")]
|
||||||
[Tooltip("Prefab for HallDoubleRoom '+' (Crossroad connection - 4-way intersection).")]
|
[Tooltip("Prefab for HallDoubleRoom '+' (Crossroad connection - 4-way intersection).")]
|
||||||
|
[AssetsOnly]
|
||||||
public GameObject hallDoubleRoomPrefab;
|
public GameObject hallDoubleRoomPrefab;
|
||||||
|
[FoldoutGroup("Modular Hallway Prefabs/HallDoubleRoom '+' (Crossroad)")]
|
||||||
|
[AssetsOnly]
|
||||||
|
public GameObject[] hallDoubleRoomPrefabs;
|
||||||
|
|
||||||
|
[FoldoutGroup("Modular Hallway Prefabs/HallT '⊢' (T-Junction)")]
|
||||||
[Tooltip("Prefab for HallT '⊢' (T-Junction connection - 3-way intersection).")]
|
[Tooltip("Prefab for HallT '⊢' (T-Junction connection - 3-way intersection).")]
|
||||||
|
[AssetsOnly]
|
||||||
public GameObject hallTPrefab;
|
public GameObject hallTPrefab;
|
||||||
|
[FoldoutGroup("Modular Hallway Prefabs/HallT '⊢' (T-Junction)")]
|
||||||
|
[AssetsOnly]
|
||||||
|
public GameObject[] hallTPrefabs;
|
||||||
|
|
||||||
|
[FoldoutGroup("Modular Hallway Prefabs/Turn 'L' (Corner)")]
|
||||||
[Tooltip("Prefab for turn 'L' (Corner connection - 2 adjacent paths).")]
|
[Tooltip("Prefab for turn 'L' (Corner connection - 2 adjacent paths).")]
|
||||||
|
[AssetsOnly]
|
||||||
public GameObject turnPrefab;
|
public GameObject turnPrefab;
|
||||||
|
[FoldoutGroup("Modular Hallway Prefabs/Turn 'L' (Corner)")]
|
||||||
|
[AssetsOnly]
|
||||||
|
public GameObject[] turnPrefabs;
|
||||||
|
|
||||||
|
[FoldoutGroup("Modular Hallway Prefabs/U-Turn 'U' (Dead end)")]
|
||||||
[Tooltip("Prefab for U-Turn 'U' (Dead end - 1 path).")]
|
[Tooltip("Prefab for U-Turn 'U' (Dead end - 1 path).")]
|
||||||
|
[AssetsOnly]
|
||||||
public GameObject uTurnPrefab;
|
public GameObject uTurnPrefab;
|
||||||
|
[FoldoutGroup("Modular Hallway Prefabs/U-Turn 'U' (Dead end)")]
|
||||||
|
[AssetsOnly]
|
||||||
|
public GameObject[] uTurnPrefabs;
|
||||||
|
|
||||||
[Header("Special Modular Prefabs")]
|
[FoldoutGroup("Special Modular Prefabs")]
|
||||||
|
[FoldoutGroup("Special Modular Prefabs/Beginning (Start)")]
|
||||||
[Tooltip("Prefab for the Beginning cell (player spawn point). Auto-rotates based on neighbors.")]
|
[Tooltip("Prefab for the Beginning cell (player spawn point). Auto-rotates based on neighbors.")]
|
||||||
|
[AssetsOnly]
|
||||||
public GameObject beginningPrefab;
|
public GameObject beginningPrefab;
|
||||||
[Tooltip("Prefab for the End cell (player exit point). Auto-rotates based on neighbors.")]
|
[FoldoutGroup("Special Modular Prefabs/Beginning (Start)")]
|
||||||
public GameObject endPrefab;
|
[AssetsOnly]
|
||||||
[Tooltip("Prefab for connecting to the next floor. Spawns on the lower floor and acts as a dead-end piece.")]
|
public GameObject[] beginningPrefabs;
|
||||||
public GameObject stairPrefab;
|
|
||||||
|
|
||||||
[Header("Preview Mode Settings (Phase 1)")]
|
[FoldoutGroup("Special Modular Prefabs/End (Exit)")]
|
||||||
|
[Tooltip("Prefab for the End cell (player exit point). Auto-rotates based on neighbors.")]
|
||||||
|
[AssetsOnly]
|
||||||
|
public GameObject endPrefab;
|
||||||
|
[FoldoutGroup("Special Modular Prefabs/End (Exit)")]
|
||||||
|
[AssetsOnly]
|
||||||
|
public GameObject[] endPrefabs;
|
||||||
|
|
||||||
|
[FoldoutGroup("Special Modular Prefabs/Stairs (Multi-floor)")]
|
||||||
|
[Tooltip("Prefab for connecting to the next floor. Spawns on the lower floor and acts as a dead-end piece.")]
|
||||||
|
[AssetsOnly]
|
||||||
|
public GameObject stairPrefab;
|
||||||
|
[FoldoutGroup("Special Modular Prefabs/Stairs (Multi-floor)")]
|
||||||
|
[AssetsOnly]
|
||||||
|
public GameObject[] stairPrefabs;
|
||||||
|
|
||||||
|
[FoldoutGroup("Preview Mode Settings")]
|
||||||
[Tooltip("If true, the spawner will only spawn simple preview blocks instead of full 3D modular pieces.")]
|
[Tooltip("If true, the spawner will only spawn simple preview blocks instead of full 3D modular pieces.")]
|
||||||
public bool isPreviewMode = false;
|
public bool isPreviewMode = false;
|
||||||
|
|
||||||
|
[FoldoutGroup("Preview Mode Settings")]
|
||||||
[Tooltip("Simple prefab to represent carved paths during the algorithm phase (e.g. a flat plane or basic cube).")]
|
[Tooltip("Simple prefab to represent carved paths during the algorithm phase (e.g. a flat plane or basic cube).")]
|
||||||
|
[ShowIf("isPreviewMode")]
|
||||||
|
[AssetsOnly]
|
||||||
public GameObject previewPathPrefab;
|
public GameObject previewPathPrefab;
|
||||||
|
|
||||||
|
[FoldoutGroup("Preview Mode Settings")]
|
||||||
[Tooltip("Simple prefab to represent walls during the algorithm phase (optional, can be left null).")]
|
[Tooltip("Simple prefab to represent walls during the algorithm phase (optional, can be left null).")]
|
||||||
|
[ShowIf("isPreviewMode")]
|
||||||
|
[AssetsOnly]
|
||||||
public GameObject previewWallPrefab;
|
public GameObject previewWallPrefab;
|
||||||
|
|
||||||
[Header("Highlight Prefabs (Animation Only)")]
|
[FoldoutGroup("Highlight Prefabs (Animation Only)")]
|
||||||
|
[AssetsOnly]
|
||||||
public GameObject searchHeadPrefab;
|
public GameObject searchHeadPrefab;
|
||||||
|
[FoldoutGroup("Highlight Prefabs (Animation Only)")]
|
||||||
|
[AssetsOnly]
|
||||||
public GameObject frontierPrefab;
|
public GameObject frontierPrefab;
|
||||||
|
[FoldoutGroup("Highlight Prefabs (Animation Only)")]
|
||||||
|
[AssetsOnly]
|
||||||
public GameObject evaluatingPrefab;
|
public GameObject evaluatingPrefab;
|
||||||
|
|
||||||
[Header("Rotation Offsets (Degrees)")]
|
[FoldoutGroup("Offsets (Rotation & Height)")]
|
||||||
[Tooltip("Rotation offset added to Hall 'I' prefab.")]
|
[Tooltip("Rotation offset added to Hall 'I' prefab.")]
|
||||||
public float hallRotationOffset = 0f;
|
public float hallRotationOffset = 0f;
|
||||||
|
[FoldoutGroup("Offsets (Rotation & Height)")]
|
||||||
[Tooltip("Rotation offset added to HallDoubleRoom '+' prefab.")]
|
[Tooltip("Rotation offset added to HallDoubleRoom '+' prefab.")]
|
||||||
public float hallDoubleRoomRotationOffset = 0f;
|
public float hallDoubleRoomRotationOffset = 0f;
|
||||||
|
[FoldoutGroup("Offsets (Rotation & Height)")]
|
||||||
[Tooltip("Rotation offset added to HallT '⊢' prefab.")]
|
[Tooltip("Rotation offset added to HallT '⊢' prefab.")]
|
||||||
public float hallTRotationOffset = 0f;
|
public float hallTRotationOffset = 0f;
|
||||||
|
[FoldoutGroup("Offsets (Rotation & Height)")]
|
||||||
[Tooltip("Rotation offset added to turn 'L' prefab.")]
|
[Tooltip("Rotation offset added to turn 'L' prefab.")]
|
||||||
public float turnRotationOffset = 0f;
|
public float turnRotationOffset = 0f;
|
||||||
|
[FoldoutGroup("Offsets (Rotation & Height)")]
|
||||||
[Tooltip("Rotation offset added to U-Turn 'U' prefab.")]
|
[Tooltip("Rotation offset added to U-Turn 'U' prefab.")]
|
||||||
public float uTurnRotationOffset = 0f;
|
public float uTurnRotationOffset = 0f;
|
||||||
|
[FoldoutGroup("Offsets (Rotation & Height)")]
|
||||||
[Tooltip("Rotation offset added to Beginning prefab.")]
|
[Tooltip("Rotation offset added to Beginning prefab.")]
|
||||||
public float beginningRotationOffset = 0f;
|
public float beginningRotationOffset = 0f;
|
||||||
|
[FoldoutGroup("Offsets (Rotation & Height)")]
|
||||||
[Tooltip("Rotation offset added to End prefab.")]
|
[Tooltip("Rotation offset added to End prefab.")]
|
||||||
public float endRotationOffset = 0f;
|
public float endRotationOffset = 0f;
|
||||||
|
[FoldoutGroup("Offsets (Rotation & Height)")]
|
||||||
[Tooltip("Rotation offset added to Stair prefab.")]
|
[Tooltip("Rotation offset added to Stair prefab.")]
|
||||||
public float stairRotationOffset = 0f;
|
public float stairRotationOffset = 0f;
|
||||||
|
[FoldoutGroup("Offsets (Rotation & Height)")]
|
||||||
[Tooltip("Height offset added to Stair prefab.")]
|
[Tooltip("Height offset added to Stair prefab.")]
|
||||||
public float stairHeightOffset = 0f;
|
public float stairHeightOffset = 0f;
|
||||||
|
|
||||||
[Header("Spacing Settings")]
|
[FoldoutGroup("Spacing Settings")]
|
||||||
[Tooltip("Physical distance between each grid cell center.")]
|
[Tooltip("Physical distance between each grid cell center.")]
|
||||||
|
[MinValue(0.1f)]
|
||||||
public float spacing = 3.0f;
|
public float spacing = 3.0f;
|
||||||
|
|
||||||
private struct SpawnedCellData
|
private struct SpawnedCellData
|
||||||
@@ -236,15 +303,15 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
{
|
{
|
||||||
if (type == MazeReworkCellType.Start && beginningPrefab != null)
|
if (type == MazeReworkCellType.Start && beginningPrefab != null)
|
||||||
{
|
{
|
||||||
(_, float baseRot) = GetModularPrefabAndRotation(grid, x, z, width, depth);
|
(_, float baseRot) = GetModularPrefabAndRotation(grid, x, z, width, depth, yOffset);
|
||||||
targetPrefab = beginningPrefab;
|
targetPrefab = GetRandomPrefab(beginningPrefab, beginningPrefabs, x, z, yOffset);
|
||||||
targetRot = baseRot + beginningRotationOffset;
|
targetRot = baseRot + beginningRotationOffset;
|
||||||
targetName = "Beginning";
|
targetName = "Beginning";
|
||||||
}
|
}
|
||||||
else if (type == MazeReworkCellType.End && endPrefab != null)
|
else if (type == MazeReworkCellType.End && endPrefab != null)
|
||||||
{
|
{
|
||||||
(_, float baseRot) = GetModularPrefabAndRotation(grid, x, z, width, depth);
|
(_, float baseRot) = GetModularPrefabAndRotation(grid, x, z, width, depth, yOffset);
|
||||||
targetPrefab = endPrefab;
|
targetPrefab = GetRandomPrefab(endPrefab, endPrefabs, x, z, yOffset);
|
||||||
targetRot = baseRot + endRotationOffset;
|
targetRot = baseRot + endRotationOffset;
|
||||||
targetName = "End";
|
targetName = "End";
|
||||||
}
|
}
|
||||||
@@ -252,15 +319,15 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
{
|
{
|
||||||
if (stairPrefab != null)
|
if (stairPrefab != null)
|
||||||
{
|
{
|
||||||
(_, float baseRot) = GetModularPrefabAndRotation(grid, x, z, width, depth);
|
(_, float baseRot) = GetModularPrefabAndRotation(grid, x, z, width, depth, yOffset);
|
||||||
targetPrefab = stairPrefab;
|
targetPrefab = GetRandomPrefab(stairPrefab, stairPrefabs, x, z, yOffset);
|
||||||
targetRot = baseRot + stairRotationOffset;
|
targetRot = baseRot + stairRotationOffset;
|
||||||
targetName = "StairConnection";
|
targetName = "StairConnection";
|
||||||
yOffset += stairHeightOffset;
|
yOffset += stairHeightOffset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(targetPrefab, targetRot) = GetModularPrefabAndRotation(grid, x, z, width, depth);
|
(targetPrefab, targetRot) = GetModularPrefabAndRotation(grid, x, z, width, depth, yOffset);
|
||||||
targetName = $"{type}";
|
targetName = $"{type}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -273,7 +340,7 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(targetPrefab, targetRot) = GetModularPrefabAndRotation(grid, x, z, width, depth);
|
(targetPrefab, targetRot) = GetModularPrefabAndRotation(grid, x, z, width, depth, yOffset);
|
||||||
targetName = $"{type}";
|
targetName = $"{type}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,7 +402,18 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (GameObject, float) GetModularPrefabAndRotation(MazeReworkCellType[,] grid, int x, int z, int width, int depth)
|
private GameObject GetRandomPrefab(GameObject single, GameObject[] array, int x, int z, float yOffset)
|
||||||
|
{
|
||||||
|
if (array != null && array.Length > 0)
|
||||||
|
{
|
||||||
|
int hash = (x * 73856093) ^ (z * 19349663) ^ (Mathf.RoundToInt(yOffset * 100f) * 83492791);
|
||||||
|
System.Random rng = new System.Random(hash);
|
||||||
|
return array[rng.Next(array.Length)];
|
||||||
|
}
|
||||||
|
return single;
|
||||||
|
}
|
||||||
|
|
||||||
|
private (GameObject, float) GetModularPrefabAndRotation(MazeReworkCellType[,] grid, int x, int z, int width, int depth, float yOffset)
|
||||||
{
|
{
|
||||||
bool top = IsPath(grid, x, z + 1, width, depth);
|
bool top = IsPath(grid, x, z + 1, width, depth);
|
||||||
bool right = IsPath(grid, x + 1, z, width, depth);
|
bool right = IsPath(grid, x + 1, z, width, depth);
|
||||||
@@ -351,32 +429,32 @@ namespace Baba_yaga.GameSetup.MazeRework
|
|||||||
switch (mask)
|
switch (mask)
|
||||||
{
|
{
|
||||||
// --- 1 open connection: U-Turn "U" ---
|
// --- 1 open connection: U-Turn "U" ---
|
||||||
case 1: return (uTurnPrefab, 0f + uTurnRotationOffset); // Open to Top
|
case 1: return (GetRandomPrefab(uTurnPrefab, uTurnPrefabs, x, z, yOffset), 0f + uTurnRotationOffset); // Open to Top
|
||||||
case 2: return (uTurnPrefab, 90f + uTurnRotationOffset); // Open to Right
|
case 2: return (GetRandomPrefab(uTurnPrefab, uTurnPrefabs, x, z, yOffset), 90f + uTurnRotationOffset); // Open to Right
|
||||||
case 4: return (uTurnPrefab, 180f + uTurnRotationOffset); // Open to Bottom
|
case 4: return (GetRandomPrefab(uTurnPrefab, uTurnPrefabs, x, z, yOffset), 180f + uTurnRotationOffset); // Open to Bottom
|
||||||
case 8: return (uTurnPrefab, 270f + uTurnRotationOffset); // Open to Left
|
case 8: return (GetRandomPrefab(uTurnPrefab, uTurnPrefabs, x, z, yOffset), 270f + uTurnRotationOffset); // Open to Left
|
||||||
|
|
||||||
// --- 2 opposite open connections: Hall "I" ---
|
// --- 2 opposite open connections: Hall "I" ---
|
||||||
case 5: return (hallPrefab, 0f + hallRotationOffset); // Open to Top & Bottom
|
case 5: return (GetRandomPrefab(hallPrefab, hallPrefabs, x, z, yOffset), 0f + hallRotationOffset); // Open to Top & Bottom
|
||||||
case 10: return (hallPrefab, 90f + hallRotationOffset); // Open to Left & Right
|
case 10: return (GetRandomPrefab(hallPrefab, hallPrefabs, x, z, yOffset), 90f + hallRotationOffset); // Open to Left & Right
|
||||||
|
|
||||||
// --- 2 adjacent open connections: turn "L" ---
|
// --- 2 adjacent open connections: turn "L" ---
|
||||||
case 3: return (turnPrefab, 0f + turnRotationOffset); // Open to Top & Right
|
case 3: return (GetRandomPrefab(turnPrefab, turnPrefabs, x, z, yOffset), 0f + turnRotationOffset); // Open to Top & Right
|
||||||
case 6: return (turnPrefab, 90f + turnRotationOffset); // Open to Right & Bottom
|
case 6: return (GetRandomPrefab(turnPrefab, turnPrefabs, x, z, yOffset), 90f + turnRotationOffset); // Open to Right & Bottom
|
||||||
case 12: return (turnPrefab, 180f + turnRotationOffset); // Open to Bottom & Left
|
case 12: return (GetRandomPrefab(turnPrefab, turnPrefabs, x, z, yOffset), 180f + turnRotationOffset); // Open to Bottom & Left
|
||||||
case 9: return (turnPrefab, 270f + turnRotationOffset); // Open to Left & Top
|
case 9: return (GetRandomPrefab(turnPrefab, turnPrefabs, x, z, yOffset), 270f + turnRotationOffset); // Open to Left & Top
|
||||||
|
|
||||||
// --- 3 open connections: HallT "⊢" ---
|
// --- 3 open connections: HallT "⊢" ---
|
||||||
case 11: return (hallTPrefab, 0f + hallTRotationOffset); // Open to Top, Right, Left (no Bottom)
|
case 11: return (GetRandomPrefab(hallTPrefab, hallTPrefabs, x, z, yOffset), 0f + hallTRotationOffset); // Open to Top, Right, Left (no Bottom)
|
||||||
case 7: return (hallTPrefab, 90f + hallTRotationOffset); // Open to Top, Right, Bottom (no Left)
|
case 7: return (GetRandomPrefab(hallTPrefab, hallTPrefabs, x, z, yOffset), 90f + hallTRotationOffset); // Open to Top, Right, Bottom (no Left)
|
||||||
case 14: return (hallTPrefab, 180f + hallTRotationOffset); // Open to Right, Bottom, Left (no Top)
|
case 14: return (GetRandomPrefab(hallTPrefab, hallTPrefabs, x, z, yOffset), 180f + hallTRotationOffset); // Open to Right, Bottom, Left (no Top)
|
||||||
case 13: return (hallTPrefab, 270f + hallTRotationOffset); // Open to Bottom, Left, Top (no Right)
|
case 13: return (GetRandomPrefab(hallTPrefab, hallTPrefabs, x, z, yOffset), 270f + hallTRotationOffset); // Open to Bottom, Left, Top (no Right)
|
||||||
|
|
||||||
// --- 4 open connections: HallDoubleRoom "+" ---
|
// --- 4 open connections: HallDoubleRoom "+" ---
|
||||||
case 15: return (hallDoubleRoomPrefab, 0f + hallDoubleRoomRotationOffset); // Open in all 4 directions
|
case 15: return (GetRandomPrefab(hallDoubleRoomPrefab, hallDoubleRoomPrefabs, x, z, yOffset), 0f + hallDoubleRoomRotationOffset); // Open in all 4 directions
|
||||||
|
|
||||||
// Fallback for isolated cells (0 connections)
|
// Fallback for isolated cells (0 connections)
|
||||||
default: return (uTurnPrefab, 0f + uTurnRotationOffset);
|
default: return (GetRandomPrefab(uTurnPrefab, uTurnPrefabs, x, z, yOffset), 0f + uTurnRotationOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user