From 8d66a062136029609749dbfda22dc6de7a0a0ee5 Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Mon, 9 Dec 2024 10:17:13 -0500 Subject: [PATCH] Created a basic procedural generator. I'm going to rework it as a lot should be improved upon. --- .editorconfig | 4 + Assets/Prefabs.meta | 8 + Assets/Prefabs/Resources.meta | 8 + Assets/Prefabs/Resources/Rooms.meta | 8 + .../Resources/Rooms/debug.test1.prefab | 234 ++++++++++++++++++ .../Resources/Rooms/debug.test1.prefab.meta | 7 + Assets/Scenes/SampleScene.unity | 78 ++++++ Assets/Scripts.meta | 8 + Assets/Scripts/EditorInterface.meta | 8 + .../Scripts/EditorInterface/GizmosHelper.cs | 31 +++ .../EditorInterface/GizmosHelper.cs.meta | 11 + Assets/Scripts/ObjectModels.meta | 8 + Assets/Scripts/ObjectModels/Singleton.cs | 18 ++ Assets/Scripts/ObjectModels/Singleton.cs.meta | 11 + Assets/Scripts/RoomGeneration.meta | 8 + .../RoomGeneration/DungeonGenerator.cs | 72 ++++++ .../RoomGeneration/DungeonGenerator.cs.meta | 11 + Assets/Scripts/RoomGeneration/RoomDoor.cs | 18 ++ .../Scripts/RoomGeneration/RoomDoor.cs.meta | 11 + Assets/Scripts/RoomGeneration/RoomItem.cs | 35 +++ .../Scripts/RoomGeneration/RoomItem.cs.meta | 11 + Assets/Scripts/RoomGeneration/RoomObject.cs | 56 +++++ .../Scripts/RoomGeneration/RoomObject.cs.meta | 11 + 23 files changed, 675 insertions(+) create mode 100644 .editorconfig create mode 100644 Assets/Prefabs.meta create mode 100644 Assets/Prefabs/Resources.meta create mode 100644 Assets/Prefabs/Resources/Rooms.meta create mode 100644 Assets/Prefabs/Resources/Rooms/debug.test1.prefab create mode 100644 Assets/Prefabs/Resources/Rooms/debug.test1.prefab.meta create mode 100644 Assets/Scripts.meta create mode 100644 Assets/Scripts/EditorInterface.meta create mode 100644 Assets/Scripts/EditorInterface/GizmosHelper.cs create mode 100644 Assets/Scripts/EditorInterface/GizmosHelper.cs.meta create mode 100644 Assets/Scripts/ObjectModels.meta create mode 100644 Assets/Scripts/ObjectModels/Singleton.cs create mode 100644 Assets/Scripts/ObjectModels/Singleton.cs.meta create mode 100644 Assets/Scripts/RoomGeneration.meta create mode 100644 Assets/Scripts/RoomGeneration/DungeonGenerator.cs create mode 100644 Assets/Scripts/RoomGeneration/DungeonGenerator.cs.meta create mode 100644 Assets/Scripts/RoomGeneration/RoomDoor.cs create mode 100644 Assets/Scripts/RoomGeneration/RoomDoor.cs.meta create mode 100644 Assets/Scripts/RoomGeneration/RoomItem.cs create mode 100644 Assets/Scripts/RoomGeneration/RoomItem.cs.meta create mode 100644 Assets/Scripts/RoomGeneration/RoomObject.cs create mode 100644 Assets/Scripts/RoomGeneration/RoomObject.cs.meta diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e69c135 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# IDE0051: Remove unused private members +dotnet_diagnostic.IDE0051.severity = none diff --git a/Assets/Prefabs.meta b/Assets/Prefabs.meta new file mode 100644 index 0000000..ee6c6fa --- /dev/null +++ b/Assets/Prefabs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f8c99dcb732bee84cbb9b20584570e82 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Resources.meta b/Assets/Prefabs/Resources.meta new file mode 100644 index 0000000..a2785da --- /dev/null +++ b/Assets/Prefabs/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 93def57754ce4bd4bad5d5f3a4ecbf9a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Resources/Rooms.meta b/Assets/Prefabs/Resources/Rooms.meta new file mode 100644 index 0000000..4f820ab --- /dev/null +++ b/Assets/Prefabs/Resources/Rooms.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3151970cdb0c552418f774a4073b25e6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Resources/Rooms/debug.test1.prefab b/Assets/Prefabs/Resources/Rooms/debug.test1.prefab new file mode 100644 index 0000000..c67ed11 --- /dev/null +++ b/Assets/Prefabs/Resources/Rooms/debug.test1.prefab @@ -0,0 +1,234 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1513129216089456175 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 422348202299819723} + - component: {fileID: 2357044271177384697} + m_Layer: 0 + m_Name: Door D + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &422348202299819723 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1513129216089456175} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: -4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2101345830686511700} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &2357044271177384697 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1513129216089456175} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8ab941518ca8a4642828187df902b1e0, type: 3} + m_Name: + m_EditorClassIdentifier: + Tag: vertical +--- !u!1 &1912872275816598801 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 646947909993633888} + - component: {fileID: 1012738459284175318} + m_Layer: 0 + m_Name: Door R + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &646947909993633888 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1912872275816598801} + m_LocalRotation: {x: 0, y: 0, z: 0.7071068, w: 0.7071068} + m_LocalPosition: {x: 5, y: -0.0000011920928, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2101345830686511700} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 90} +--- !u!114 &1012738459284175318 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1912872275816598801} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8ab941518ca8a4642828187df902b1e0, type: 3} + m_Name: + m_EditorClassIdentifier: + Tag: horizontal +--- !u!1 &2101345829801090270 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2101345829801090264} + - component: {fileID: 2101345829801090271} + m_Layer: 0 + m_Name: Door L + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2101345829801090264 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2101345829801090270} + m_LocalRotation: {x: 0, y: 0, z: -0.7071068, w: 0.7071068} + m_LocalPosition: {x: -5, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2101345830686511700} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: -90} +--- !u!114 &2101345829801090271 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2101345829801090270} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8ab941518ca8a4642828187df902b1e0, type: 3} + m_Name: + m_EditorClassIdentifier: + Tag: horizontal +--- !u!1 &2101345830686511723 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2101345830686511700} + - component: {fileID: 2101345830686511701} + m_Layer: 0 + m_Name: debug.test1 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2101345830686511700 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2101345830686511723} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 7175683798590047672} + - {fileID: 422348202299819723} + - {fileID: 2101345829801090264} + - {fileID: 646947909993633888} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &2101345830686511701 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2101345830686511723} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6268a80b1893dea4da88a977847d0df1, type: 3} + m_Name: + m_EditorClassIdentifier: + Identifier: debug.test1 + Bounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 5, y: 4, z: 0} + Doors: + - {fileID: 5516082331950511926} + - {fileID: 2357044271177384697} + - {fileID: 2101345829801090271} + - {fileID: 1012738459284175318} +--- !u!1 &9158382049854172236 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7175683798590047672} + - component: {fileID: 5516082331950511926} + m_Layer: 0 + m_Name: Door U + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7175683798590047672 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9158382049854172236} + m_LocalRotation: {x: 0, y: 0, z: 1, w: 0} + m_LocalPosition: {x: 0, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2101345830686511700} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 180} +--- !u!114 &5516082331950511926 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9158382049854172236} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8ab941518ca8a4642828187df902b1e0, type: 3} + m_Name: + m_EditorClassIdentifier: + Tag: vertical diff --git a/Assets/Prefabs/Resources/Rooms/debug.test1.prefab.meta b/Assets/Prefabs/Resources/Rooms/debug.test1.prefab.meta new file mode 100644 index 0000000..877070c --- /dev/null +++ b/Assets/Prefabs/Resources/Rooms/debug.test1.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e460ac35ac4587e498e7133f9e3962cf +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index fa3fc63..44e7bef 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -118,6 +118,8 @@ NavMeshSettings: manualTileSize: 0 tileSize: 256 accuratePlacement: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 debug: m_Flags: 0 m_NavMeshData: {fileID: 0} @@ -204,3 +206,79 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &754085557 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 754085558} + m_Layer: 0 + m_Name: Root + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &754085558 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 754085557} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1726388856 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1726388858} + - component: {fileID: 1726388857} + m_Layer: 0 + m_Name: Generator + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1726388857 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1726388856} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 97bc65bc89d5f1949914183b68f0e48b, type: 3} + m_Name: + m_EditorClassIdentifier: + DungeonRoot: {fileID: 754085558} + StartingRoomId: debug.test1 + RoomCountRange: {x: 20, y: 50} +--- !u!4 &1726388858 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1726388856} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/Scripts.meta b/Assets/Scripts.meta new file mode 100644 index 0000000..409667b --- /dev/null +++ b/Assets/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6d99eb921b17dad4e8658805e779f3d2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/EditorInterface.meta b/Assets/Scripts/EditorInterface.meta new file mode 100644 index 0000000..8a09fdb --- /dev/null +++ b/Assets/Scripts/EditorInterface.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0a0b20ea41f112d4898b0127993d03da +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/EditorInterface/GizmosHelper.cs b/Assets/Scripts/EditorInterface/GizmosHelper.cs new file mode 100644 index 0000000..d6f716a --- /dev/null +++ b/Assets/Scripts/EditorInterface/GizmosHelper.cs @@ -0,0 +1,31 @@ +using UnityEngine; + +public static class GizmosHelper +{ + public static void DrawLine(Transform transform, Vector3 from, Vector3 to) => DrawPoints(transform, new Vector3[2] + { + from, + to + }); + public static void DrawPoints(Transform transform, Vector3[] points) + { + // Apply rotation and position. + for (int i = 0; i < points.Length; i++) + { + points[i] = transform.rotation * points[i] + transform.position; + } + + // Draw points. + for (int i = 0; i < points.Length; i++) + { + Gizmos.DrawLine(points[i], points[(i + 1) % points.Length]); + } + } + public static void DrawRect(Transform transform, Bounds bounds) => DrawPoints(transform, new Vector3[4] + { + new Vector2(bounds.min.x, bounds.min.y), + new Vector2(bounds.max.x, bounds.min.y), + new Vector2(bounds.max.x, bounds.max.y), + new Vector2(bounds.min.x, bounds.max.y) + }); +} diff --git a/Assets/Scripts/EditorInterface/GizmosHelper.cs.meta b/Assets/Scripts/EditorInterface/GizmosHelper.cs.meta new file mode 100644 index 0000000..1e1c60c --- /dev/null +++ b/Assets/Scripts/EditorInterface/GizmosHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d17a502c10c86db4d9e753547debbfec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ObjectModels.meta b/Assets/Scripts/ObjectModels.meta new file mode 100644 index 0000000..f7da6b9 --- /dev/null +++ b/Assets/Scripts/ObjectModels.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7a850575e29641144b8292c0da8ddc94 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ObjectModels/Singleton.cs b/Assets/Scripts/ObjectModels/Singleton.cs new file mode 100644 index 0000000..34fbc72 --- /dev/null +++ b/Assets/Scripts/ObjectModels/Singleton.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +public abstract class Singleton : MonoBehaviour + where T : Singleton +{ + public static T Instance { get; private set; } + + private void Awake() + { + if (Instance != null) + { + Debug.LogWarning($"Duplicate instance of {nameof(T)}! Ignoring this one."); + Destroy(this); + return; + } + Instance = (T)this; + } +} diff --git a/Assets/Scripts/ObjectModels/Singleton.cs.meta b/Assets/Scripts/ObjectModels/Singleton.cs.meta new file mode 100644 index 0000000..1a1d095 --- /dev/null +++ b/Assets/Scripts/ObjectModels/Singleton.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c12da831f15ec254b8eb03f5a6cb2e4c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/RoomGeneration.meta b/Assets/Scripts/RoomGeneration.meta new file mode 100644 index 0000000..30d42dd --- /dev/null +++ b/Assets/Scripts/RoomGeneration.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f0c5cb243264b844fbe832fd51d6355b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/RoomGeneration/DungeonGenerator.cs b/Assets/Scripts/RoomGeneration/DungeonGenerator.cs new file mode 100644 index 0000000..fa4242f --- /dev/null +++ b/Assets/Scripts/RoomGeneration/DungeonGenerator.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +public class DungeonGenerator : Singleton +{ + // TODO: Add a weighting system. + + public Transform DungeonRoot; + public string StartingRoomId; + public Vector2Int RoomCountRange; + + private RoomObject[] possibleRooms; + + private void Start() + { + possibleRooms = Resources.LoadAll("Rooms"); + Debug.Log($"Loaded {possibleRooms.Length} room assets."); + MakeDungeon(); + } + + public void MakeDungeon() + { + int rooms = Random.Range(RoomCountRange.x, RoomCountRange.y + 1); + Debug.Log($"{rooms} rooms will be generated."); + + List emptyDoors = new List(); + RoomObject activeRoom = GetRoomById(StartingRoomId, true); + emptyDoors.AddRange(activeRoom.Doors); + + while (rooms > 0 && emptyDoors.Count > 0) + { + // Pick random empty door and spawn a room there. + RoomDoor door = emptyDoors[Random.Range(0, emptyDoors.Count)]; + RoomDoor matchingDoor = GetRoomDoorByTag(door.Tag, true); + if (matchingDoor == null) + { + emptyDoors.Remove(door); + continue; + } + + matchingDoor.SetRoomRotationByDoor(door.transform.rotation.eulerAngles); + matchingDoor.SetRoomPositionByDoor(door.transform.position); + + List extraDoors = new List(matchingDoor.Room.Doors); + extraDoors.Remove(matchingDoor); + emptyDoors.AddRange(extraDoors); + + rooms--; + } + } + + public RoomObject GetRoomById(string id, bool instantiate) + { + RoomObject[] could = possibleRooms.Where(x => x.Identifier.StartsWith(id)).ToArray(); + RoomObject chosen = could[Random.Range(0, could.Length)]; + + if (instantiate) return Instantiate(chosen, DungeonRoot); + else return chosen; + } + public RoomDoor GetRoomDoorByTag(string tag, bool instantiate) + { + RoomObject[] could = possibleRooms.Where(x => x.Doors.Any(y => y.Tag.StartsWith(tag))).ToArray(); + if (could.Length == 0) return null; + + RoomObject chosen = could[Random.Range(0, could.Length)]; + if (instantiate) chosen = Instantiate(chosen, DungeonRoot); + + RoomDoor[] couldDoors = chosen.Doors.Where(x => x.Tag.StartsWith(tag)).ToArray(); + return couldDoors[Random.Range(0, couldDoors.Length)]; + } +} diff --git a/Assets/Scripts/RoomGeneration/DungeonGenerator.cs.meta b/Assets/Scripts/RoomGeneration/DungeonGenerator.cs.meta new file mode 100644 index 0000000..41fc2c4 --- /dev/null +++ b/Assets/Scripts/RoomGeneration/DungeonGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 97bc65bc89d5f1949914183b68f0e48b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/RoomGeneration/RoomDoor.cs b/Assets/Scripts/RoomGeneration/RoomDoor.cs new file mode 100644 index 0000000..362b560 --- /dev/null +++ b/Assets/Scripts/RoomGeneration/RoomDoor.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +public class RoomDoor : RoomItem +{ + public string Tag; + + public void SetRoomRotationByDoor(Vector3 desiredDoorRotation) + { + Room.transform.rotation *= Quaternion.FromToRotation(Room.transform.rotation.eulerAngles, desiredDoorRotation); + } + public void SetRoomPositionByDoor(Vector2 desiredDoorPosition) + { + Vector2 curPos = transform.position; + Vector2 diff = desiredDoorPosition - curPos; + + Room.transform.position += (Vector3)diff; + } +} diff --git a/Assets/Scripts/RoomGeneration/RoomDoor.cs.meta b/Assets/Scripts/RoomGeneration/RoomDoor.cs.meta new file mode 100644 index 0000000..59d212e --- /dev/null +++ b/Assets/Scripts/RoomGeneration/RoomDoor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ab941518ca8a4642828187df902b1e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/RoomGeneration/RoomItem.cs b/Assets/Scripts/RoomGeneration/RoomItem.cs new file mode 100644 index 0000000..56bc89c --- /dev/null +++ b/Assets/Scripts/RoomGeneration/RoomItem.cs @@ -0,0 +1,35 @@ +using UnityEngine; + +[ExecuteAlways] +public abstract class RoomItem : MonoBehaviour +{ + public RoomObject Room { get; private set; } + + private void Awake() + { + Room = GetComponentInParent(); + } + + private void Update() + { + if (!Application.isPlaying) + { + EditorUpdate(); + return; + } + } + private void EditorUpdate() + { + Awake(); + if (Room == null) + { + Debug.LogError("A room item must have a parent room."); + return; + } + } + + private void OnDrawGizmosSelected() + { + Room.OnDrawGizmosSelected(); + } +} diff --git a/Assets/Scripts/RoomGeneration/RoomItem.cs.meta b/Assets/Scripts/RoomGeneration/RoomItem.cs.meta new file mode 100644 index 0000000..87c48e7 --- /dev/null +++ b/Assets/Scripts/RoomGeneration/RoomItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5650535e833d8ce43b11c4b47b4df190 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/RoomGeneration/RoomObject.cs b/Assets/Scripts/RoomGeneration/RoomObject.cs new file mode 100644 index 0000000..feb9e24 --- /dev/null +++ b/Assets/Scripts/RoomGeneration/RoomObject.cs @@ -0,0 +1,56 @@ +using UnityEngine; + +[ExecuteAlways] +public class RoomObject : MonoBehaviour +{ + public string Identifier; + public Bounds Bounds; + public RoomDoor[] Doors; + + private void Awake() + { + Doors = GetComponentsInChildren(); + } + + private void Update() + { + if (!Application.isPlaying) + { + EditorUpdate(); + return; + } + } + private void EditorUpdate() + { + Awake(); + if (Bounds.extents.z != 0 || Bounds.center.z != 0) + { + Bounds.extents = (Vector2)Bounds.extents; + Bounds.size = (Vector2)Bounds.size; + } + } + + internal void OnDrawGizmos() + { + // Draw room mesh. + Gizmos.color = new Color(1, 0.5f, 0); // Orange + foreach (RoomDoor roomDoor in Doors) + { + GizmosHelper.DrawLine(transform, roomDoor.transform.localPosition, Bounds.center); + } + } + internal void OnDrawGizmosSelected() + { + // Draw room bounds. + Gizmos.color = Color.white; + GizmosHelper.DrawRect(transform, Bounds); + + // Draw each door. + Gizmos.color = Color.green; + Bounds doorBounds = new Bounds(Vector2.zero, new Vector2(2, 1)); + foreach (RoomDoor door in Doors) + { + GizmosHelper.DrawRect(door.transform, doorBounds); + } + } +} diff --git a/Assets/Scripts/RoomGeneration/RoomObject.cs.meta b/Assets/Scripts/RoomGeneration/RoomObject.cs.meta new file mode 100644 index 0000000..2e1707a --- /dev/null +++ b/Assets/Scripts/RoomGeneration/RoomObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6268a80b1893dea4da88a977847d0df1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: