generate simple room

This commit is contained in:
2022-10-28 21:19:00 +02:00
parent 347b026ade
commit ddb7ce73c9
27 changed files with 635 additions and 2519 deletions

View File

@@ -0,0 +1,18 @@
namespace Escape_Room_Engine.Engine.Scripts
{
public enum DoorType
{
Entrance = ModuleType.DoorEntrance, Exit = ModuleType.DoorExit
}
public class DoorModule : Module
{
public bool IsEntrance => IsType((ModuleType)DoorType.Entrance);
public bool IsExit => IsType((ModuleType)DoorType.Exit);
internal DoorModule(DoorType type)
{
_types.Add((ModuleType)type);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 05af827f50ab469f952abbb62109877d
timeCreated: 1667226128

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 49bc52aa373de5f4a9be95d26b4050ce
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Escape_Room_Engine.Engine.Scripts.Editor
{
public class EngineEditor : EditorWindow
{
[MenuItem("Window/Engine/Engine Editor")]
public static void ShowEditor()
{
var window = GetWindow<EngineEditor>();
window.titleContent = new GUIContent("Engine Editor");
}
public void CreateGUI()
{
var generateRoom = new Button(GenerateRoom)
{
text = Engine.DefaultEngine.NumberOfRooms == 0 ? "Generate Room" : "Regenerate Room"
};
generateRoom.SetEnabled(EditorApplication.isPlaying);
rootVisualElement.Add(generateRoom);
}
private void GenerateRoom()
{
Debug.Log("Generating new room...");
Engine.DefaultEngine.DisposeOldestRoom();
Engine.DefaultEngine.GenerateRoom();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b053e3376aa6ae646b82182855e23ead
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,49 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Escape_Room_Engine.Engine.Scripts
{
public class Engine : MonoBehaviour
{
public static Engine DefaultEngine => FindObjectOfType<Engine>();
public Material roomMaterial;
public int NumberOfRooms => _rooms.Count;
private List<Room> _rooms = new(1);
public void GenerateRoom()
{
// get the last entrance from the newest room or create a spawn passage with no entrance door for where the player will start
var entrance = NumberOfRooms > 0 ? _rooms[0].exit : new Passage();
var room = new Room(entrance);
_rooms.Add(room);
GenerateSpace(room, entrance); // TODO: rooms with more than one space
room.InstantiateRoom(transform, (_rooms.Count - 1).ToString());
}
void GenerateSpace(Room room, Passage from)
{
var exit = new Passage();
var size = new SpaceSize(Random.Range(2, 6), Random.Range(2, 6)); // TODO: no hardcoded space size
var space = new Space(size, from, exit);
room.AddSpace(space, exit);
}
/// <summary>
/// Dispose of the oldest room to save resources.
/// </summary>
public void DisposeOldestRoom()
{
if (NumberOfRooms > 0)
{
_rooms[NumberOfRooms - 1].Destroy();
_rooms.RemoveAt(NumberOfRooms - 1);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9a9b6b8b557abbb4ab172444615ebf23
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace Escape_Room_Engine.Engine.Scripts
{
public class Module
{
protected List<ModuleType> _types = new();
public bool IsType(ModuleType type)
{
return _types.Contains(type);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bef95c0b6e3be5847939fffa4294f99f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
namespace Escape_Room_Engine.Engine.Scripts
{
public enum ModuleType
{
DoorEntrance, DoorExit
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 602fa211234b4068bca5ff38a2f9593f
timeCreated: 1667230405

View File

@@ -0,0 +1,17 @@
namespace Escape_Room_Engine.Engine.Scripts
{
public class Passage
{
internal DoorModule fromOut, toIn;
internal void ConnectFrom(DoorModule door)
{
fromOut = door;
}
internal void ConnectTo(DoorModule door)
{
toIn = door;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 58b4bdd93b9843a29cf03b304553ad10
timeCreated: 1667222752

View File

@@ -0,0 +1,44 @@
using System.Collections.Generic;
using UnityEngine;
namespace Escape_Room_Engine.Engine.Scripts
{
public class Room
{
internal Passage entrance, exit;
private GameObject _roomObject;
private List<Space> _spaces = new();
internal Room(Passage entrance)
{
this.entrance = entrance;
}
internal void AddSpace(Space space, Passage spaceExit)
{
_spaces.Add(space);
exit = spaceExit;
}
internal void InstantiateRoom(Transform parent, string name)
{
_roomObject = new GameObject($"Room {name}");
_roomObject.transform.SetParent(parent);
for (var i = 0; i < _spaces.Count; i++)
{
_spaces[i].InstantiateSpace(_roomObject.transform, i.ToString());
}
}
internal void Destroy()
{
foreach (var space in _spaces)
{
space.Destroy();
}
Object.Destroy(_roomObject);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ca3aaaca7b04a5049b5d327832fe6f0a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
using System.Collections.Generic;
using UnityEngine;
namespace Escape_Room_Engine.Engine.Scripts
{
public class Space
{
// public DoorModule Entrance => (DoorModule)_modules.Find(module => module.IsType((ModuleType)DoorType.Entrance));
// public DoorModule Exit => (DoorModule)_modules.Find(module => module.IsType((ModuleType)DoorType.Exit));
private readonly SpaceSize _size;
private GameObject _spaceObject;
private List<Module> _modules = new(2);
internal Space(SpaceSize size, Passage entrance, Passage exit)
{
_size = size;
// connect the space to its passages
entrance.ConnectTo(new DoorModule(DoorType.Entrance));
AddModule(entrance.toIn);
exit.ConnectFrom(new DoorModule(DoorType.Exit));
AddModule(exit.fromOut);
}
internal void AddModule(Module module)
{
_modules.Add(module);
}
internal void InstantiateSpace(Transform parent, string name)
{
_spaceObject = new GameObject($"Space {name}");
_spaceObject.transform.SetParent(parent);
var meshFilter = _spaceObject.AddComponent<MeshFilter>();
meshFilter.mesh = GenerateMesh();
var meshRenderer = _spaceObject.AddComponent<MeshRenderer>();
meshRenderer.material = Engine.DefaultEngine.roomMaterial;
}
internal Mesh GenerateMesh()
{
var mesh = new Mesh();
float halfWidth = _size.Width / 2f, halfHeight = _size.Height / 2f;
mesh.vertices = new[]
{
new Vector3(-halfWidth, 0, -halfHeight),
new Vector3(halfWidth, 0, -halfHeight),
new Vector3(-halfWidth, 0, halfHeight),
new Vector3(halfWidth, 0, halfHeight)
};
mesh.triangles = new[]
{
0, 2, 1,
2, 3, 1
};
var normal = Vector3.up;
mesh.normals = new[]
{
normal, normal, normal, normal
};
mesh.uv = new[]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(1, 1)
};
return mesh;
}
internal void Destroy()
{
Object.Destroy(_spaceObject);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: acd43d28cfff2b640a01dd6f51f7393f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
namespace Escape_Room_Engine.Engine.Scripts
{
public readonly struct SpaceSize
{
internal SpaceSize(int width, int height)
{
Width = width;
Height = height;
}
// TODO: intersections and unions of rectangles
public int Width { get; }
public int Height { get; }
public override string ToString() => $"({Width}, {Height})";
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b70ad3679d5c48768c1d132f56dba4dd
timeCreated: 1667222427