module state game objects

This commit is contained in:
2022-11-13 20:49:32 +01:00
parent 14ab0374cc
commit 5f19adcb43
13 changed files with 251 additions and 84 deletions

View File

@@ -6,9 +6,10 @@ namespace Escape_Room_Engine.Engine.Scripts.Editor
{ {
public class EngineEditor : EditorWindow public class EngineEditor : EditorWindow
{ {
private Button _generateRoomButton, _skipCurrentRoomButton; private bool _registeredUpdateEvent;
private Button _passToNextRoomButton, _skipCurrentRoomButton;
[MenuItem("Window/Engine/Engine Editor")] [MenuItem("Window/Engine Editor")]
public static void ShowEditor() public static void ShowEditor()
{ {
var window = GetWindow<EngineEditor>(); var window = GetWindow<EngineEditor>();
@@ -17,11 +18,11 @@ namespace Escape_Room_Engine.Engine.Scripts.Editor
public void CreateGUI() public void CreateGUI()
{ {
_generateRoomButton = new Button(GenerateRoom) _passToNextRoomButton = new Button(PassToNextRoom)
{ {
text = "Generate Room" text = "Pass To Next Room"
}; };
rootVisualElement.Add(_generateRoomButton); rootVisualElement.Add(_passToNextRoomButton);
_skipCurrentRoomButton = new Button(SkipCurrentRoom) _skipCurrentRoomButton = new Button(SkipCurrentRoom)
{ {
text = "Skip Current Room" text = "Skip Current Room"
@@ -32,12 +33,11 @@ namespace Escape_Room_Engine.Engine.Scripts.Editor
UpdateUI(); UpdateUI();
} }
private void GenerateRoom() private void PassToNextRoom()
{ {
if (EditorApplication.isPlaying) if (EditorApplication.isPlaying)
{ {
Engine.DefaultEngine.HideOldestRoom(); Engine.DefaultEngine.HidePreviousRoom();
Engine.DefaultEngine.GenerateRoom();
UpdateUI(); UpdateUI();
} }
} }
@@ -53,7 +53,20 @@ namespace Escape_Room_Engine.Engine.Scripts.Editor
private void UpdateUI() private void UpdateUI()
{ {
_generateRoomButton.SetEnabled(EditorApplication.isPlaying); if (EditorApplication.isPlaying)
{
if (!_registeredUpdateEvent)
{
Engine.DefaultEngine.UpdateUIEvent += UpdateUI;
_registeredUpdateEvent = true;
}
}
else
{
_registeredUpdateEvent = false;
}
_passToNextRoomButton.SetEnabled(EditorApplication.isPlaying && Engine.DefaultEngine.NumberOfRooms > 1);
_skipCurrentRoomButton.SetEnabled(EditorApplication.isPlaying && Engine.DefaultEngine.NumberOfRooms > 0); _skipCurrentRoomButton.SetEnabled(EditorApplication.isPlaying && Engine.DefaultEngine.NumberOfRooms > 0);
} }
} }

View File

@@ -25,6 +25,9 @@ namespace Escape_Room_Engine.Engine.Scripts
} }
private static Engine _foundEngine; private static Engine _foundEngine;
public delegate void UpdateUIHandler();
public event UpdateUIHandler UpdateUIEvent;
[Required] public EngineConfiguration config; [Required] public EngineConfiguration config;
public int NumberOfRooms => _rooms.Count; public int NumberOfRooms => _rooms.Count;
@@ -38,6 +41,8 @@ namespace Escape_Room_Engine.Engine.Scripts
_playSpaceOrigin = new GameObject("Play Space Origin"); _playSpaceOrigin = new GameObject("Play Space Origin");
_playSpaceOrigin.transform.SetParent(transform); _playSpaceOrigin.transform.SetParent(transform);
_playSpaceOrigin.transform.localPosition = new Vector3(-config.playSpace.x / 2f, 0, -config.playSpace.y / 2f); _playSpaceOrigin.transform.localPosition = new Vector3(-config.playSpace.x / 2f, 0, -config.playSpace.y / 2f);
GenerateRoom();
} }
public void GenerateRoom() public void GenerateRoom()
@@ -53,6 +58,8 @@ namespace Escape_Room_Engine.Engine.Scripts
GenerateSpace(room, entrance); // TODO: rooms with more than one space GenerateSpace(room, entrance); // TODO: rooms with more than one space
room.InstantiateRoom(_playSpaceOrigin.transform, (_rooms.Count - 1).ToString()); room.InstantiateRoom(_playSpaceOrigin.transform, (_rooms.Count - 1).ToString());
UpdateUI();
} }
private void GenerateSpace(Room room, Passage entrance) private void GenerateSpace(Room room, Passage entrance)
@@ -77,14 +84,16 @@ namespace Escape_Room_Engine.Engine.Scripts
room.AddSpace(space, exit); room.AddSpace(space, exit);
} }
public void HideOldestRoom() public void HidePreviousRoom()
{ {
if (NumberOfRooms > 0) if (NumberOfRooms > 1)
{ {
_rooms[NumberOfRooms - 1].roomObject.SetActive(false); _rooms[NumberOfRooms - 2].roomObject.SetActive(false);
} }
} }
private void UpdateUI() => UpdateUIEvent?.Invoke();
// ReSharper disable once SuggestBaseTypeForParameter // ReSharper disable once SuggestBaseTypeForParameter
// ReSharper disable once UnusedMember.Local // ReSharper disable once UnusedMember.Local
private bool IsNotEmpty(List<DoorModuleDescription> modules) => modules.Count > 0; private bool IsNotEmpty(List<DoorModuleDescription> modules) => modules.Count > 0;

View File

@@ -1,6 +1,5 @@
using System; using System;
using UnityEngine; using UnityEngine;
using LogType = Escape_Room_Engine.Engine.Scripts.Utilities.LogType;
namespace Escape_Room_Engine.Engine.Scripts.Modules namespace Escape_Room_Engine.Engine.Scripts.Modules
{ {
@@ -14,19 +13,24 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
{ {
public bool IsEntrance => IsType((ModuleType)DoorType.Entrance); public bool IsEntrance => IsType((ModuleType)DoorType.Entrance);
public bool IsExit => IsType((ModuleType)DoorType.Exit); public bool IsExit => IsType((ModuleType)DoorType.Exit);
internal new DoorState State { get; private set; }
private bool _unlocked;
internal DoorModule(Space space, DoorModuleDescription description) : base(space, description) internal DoorModule(Space space, DoorModuleDescription description) : base(space, description)
{ {
srDimensions.Size = Vector2Int.one; // door always has size 1x1 srDimensions.Size = Vector2Int.one; // door always has size 1x1
} }
internal void Unlock() internal override void InstantiateModule(Transform parent)
{ {
_unlocked = true; base.InstantiateModule(parent);
Utilities.Logger.Log($"{this} has been unlocked", LogType.PuzzleFlow); space.room.AddDoor(this);
}
protected override void AddStateComponent()
{
State = moduleObject.AddComponent<DoorState>();
State.SetModule(this);
} }
public override string ToString() public override string ToString()

View File

@@ -0,0 +1,66 @@
using System;
using Escape_Room_Engine.Engine.Scripts.Utilities;
using NaughtyAttributes;
namespace Escape_Room_Engine.Engine.Scripts.Modules
{
public enum DoorEventType
{
Locked, Unlocked
}
public delegate void DoorEventHandler(DoorModule source, DoorEventType e);
public class DoorState : ModuleState
{
public event DoorEventHandler DoorEvent;
private new DoorModule Module { get; set; }
public bool Unlocked
{
get => _unlocked;
private set
{
var type =
!_unlocked && value ? Some<DoorEventType>.Of(DoorEventType.Unlocked)
: _unlocked && !value ? Some<DoorEventType>.Of(DoorEventType.Locked)
: None<DoorEventType>.New();
_unlocked = value;
type.Match(some: OnDoorEvent);
}
}
private bool _unlocked;
private void OnDoorEvent(DoorEventType type)
{
Logger.Log($"{Module} has been {type}", LogType.PuzzleFlow);
DoorEvent?.Invoke(Module, type);
}
public override void SetModule(Module module)
{
if (module is DoorModule doorModule)
{
Module = doorModule;
}
else
{
throw new Exception("Tried to set wrong type of module.");
}
}
[Button(enabledMode: EButtonEnableMode.Playmode)]
internal void Unlock()
{
Unlocked = true;
}
[Button(enabledMode: EButtonEnableMode.Playmode)]
internal void Lock()
{
Unlocked = false;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 696181e3eda449d49d4c1c88b07d7b05
timeCreated: 1668337769

View File

@@ -28,7 +28,8 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
/// <summary> /// <summary>
/// Get the room relative (<i>RR</i>) position of this module. /// Get the room relative (<i>RR</i>) position of this module.
/// </summary> /// </summary>
internal Vector2Int RrPosition => _space.ToRoomRelative(SrPosition); internal Vector2Int RrPosition => space.ToRoomRelative(SrPosition);
internal ModuleState State { get; private set; }
internal readonly ModuleDescription description; internal readonly ModuleDescription description;
internal Orientation orientation; internal Orientation orientation;
@@ -38,12 +39,13 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
/// </summary> /// </summary>
protected Dimensions srDimensions; protected Dimensions srDimensions;
private GameObject _moduleObject, _orientationObject; protected GameObject moduleObject;
private readonly Space _space; protected readonly Space space;
private GameObject _orientationObject;
internal Module(Space space, ModuleDescription description) internal Module(Space space, ModuleDescription description)
{ {
_space = space; this.space = space;
this.description = description; this.description = description;
} }
@@ -57,16 +59,16 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
/// </summary> /// </summary>
/// <param name="rrPosition">The room relative (<i>RR</i>) position of this module. Must be inside the space dimensions.</param> /// <param name="rrPosition">The room relative (<i>RR</i>) position of this module. Must be inside the space dimensions.</param>
/// <exception cref="Exception">If the position is not inside the space dimensions.</exception> /// <exception cref="Exception">If the position is not inside the space dimensions.</exception>
internal void PlaceRoomRelative(Vector2Int rrPosition) => Place(_space.ToSpaceRelative(rrPosition)); internal void PlaceRoomRelative(Vector2Int rrPosition) => Place(space.ToSpaceRelative(rrPosition));
/// <summary> /// <summary>
/// Place this module with a position relative to the space it is in. /// Place this module with a position relative to the space it is in.
/// </summary> /// </summary>
/// <param name="srPosition">The space relative (<i>SR</i>) position of this module. Must be inside the space dimensions.</param> /// <param name="srPosition">The space relative (<i>SR</i>) position of this module. Must be inside the space dimensions.</param>
/// <exception cref="Exception">If the position is not inside the space dimensions.</exception> /// <exception cref="Exception">If the position is not inside the space dimensions.</exception>
internal void Place(Vector2Int srPosition) { internal void Place(Vector2Int srPosition) {
if (_space != null && !srPosition.IsInsideRelative(_space.rrDimensions)) if (space != null && !srPosition.IsInsideRelative(space.rrDimensions))
{ {
throw new Exception($"Trying to place {this} at {srPosition}, which is outside space dimensions {_space.rrDimensions}."); throw new Exception($"Trying to place {this} at {srPosition}, which is outside space dimensions {space.rrDimensions}.");
} }
srDimensions.Position = srPosition; srDimensions.Position = srPosition;
@@ -92,19 +94,26 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
}; };
} }
internal void InstantiateModule(Transform parent) internal virtual void InstantiateModule(Transform parent)
{ {
_moduleObject = new GameObject(ToString()); moduleObject = new GameObject(ToString());
_moduleObject.transform.SetParent(parent, false); moduleObject.transform.SetParent(parent, false);
_moduleObject.transform.localPosition = new Vector3(srDimensions.x + .5f, 0, srDimensions.z + .5f); moduleObject.transform.localPosition = new Vector3(srDimensions.x + .5f, 0, srDimensions.z + .5f);
AddStateComponent();
_orientationObject = new GameObject("Orientation"); _orientationObject = new GameObject("Orientation");
_orientationObject.transform.SetParent(_moduleObject.transform, false); _orientationObject.transform.SetParent(moduleObject.transform, false);
_orientationObject.transform.Rotate(Vector3.up, (float)orientation); _orientationObject.transform.Rotate(Vector3.up, (float)orientation);
Object.Instantiate(description.modulePrefab, _orientationObject.transform, false); Object.Instantiate(description.modulePrefab, _orientationObject.transform, false);
} }
protected virtual void AddStateComponent()
{
State = moduleObject.AddComponent<ModuleState>();
State.SetModule(this);
}
public override string ToString() public override string ToString()
{ {
return $"Module ({string.Join(", ", description.types.ToList().ConvertAll(type => type.ToString()))})"; return $"Module ({string.Join(", ", description.types.ToList().ConvertAll(type => type.ToString()))})";

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Escape_Room_Engine.Engine.Scripts.Modules
{
public class ModuleState : MonoBehaviour
{
public Module Module { get; protected set; }
public virtual void SetModule(Module module) => Module = module;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: efdc32c450f7411385748449459a17b4
timeCreated: 1668180361

View File

@@ -1,57 +1,27 @@
using Escape_Room_Engine.Engine.Scripts.Utilities; using UnityEngine;
using UnityEngine;
using Logger = Escape_Room_Engine.Engine.Scripts.Utilities.Logger;
using LogType = Escape_Room_Engine.Engine.Scripts.Utilities.LogType;
namespace Escape_Room_Engine.Engine.Scripts.Modules namespace Escape_Room_Engine.Engine.Scripts.Modules
{ {
public enum PuzzleEventType
{
Reset, Solved
}
public delegate void PuzzleEventHandler(PuzzleModule source, PuzzleEventType e);
public class PuzzleModule : Module public class PuzzleModule : Module
{ {
internal event PuzzleEventHandler PuzzleEvent; internal new PuzzleState State { get; private set; }
internal bool Solved
{
get => _solved;
private set
{
var type =
!_solved && value ? Some<PuzzleEventType>.Of(PuzzleEventType.Solved)
: _solved && value ? Some<PuzzleEventType>.Of(PuzzleEventType.Reset)
: None<PuzzleEventType>.New();
_solved = value;
type.Match(some: OnPuzzleEvent);
}
}
private bool _solved;
internal PuzzleModule(Space space, PuzzleModuleDescription description) : base(space, description) internal PuzzleModule(Space space, PuzzleModuleDescription description) : base(space, description)
{ {
srDimensions.Size = Vector2Int.one; // TODO: larger modules srDimensions.Size = Vector2Int.one; // TODO: larger modules
} }
protected virtual void OnPuzzleEvent(PuzzleEventType type) internal override void InstantiateModule(Transform parent)
{ {
Logger.Log($"{this} has been {type}", LogType.PuzzleFlow); base.InstantiateModule(parent);
PuzzleEvent?.Invoke(this, type); space.room.AddPuzzle(this);
} }
public void Solve() protected override void AddStateComponent()
{ {
Solved = true; State = moduleObject.AddComponent<PuzzleState>();
} State.SetModule(this);
public override string ToString()
{
return $"Puzzle module ({(Solved ? "" : "not ")}solved)";
} }
} }
} }

View File

@@ -0,0 +1,66 @@
using System;
using Escape_Room_Engine.Engine.Scripts.Utilities;
using NaughtyAttributes;
namespace Escape_Room_Engine.Engine.Scripts.Modules
{
public enum PuzzleEventType
{
Restarted, Solved
}
public delegate void PuzzleEventHandler(PuzzleModule source, PuzzleEventType e);
public class PuzzleState : ModuleState
{
public event PuzzleEventHandler PuzzleEvent;
private new PuzzleModule Module { get; set; }
public bool Solved
{
get => _solved;
private set
{
var type =
!_solved && value ? Some<PuzzleEventType>.Of(PuzzleEventType.Solved)
: _solved && !value ? Some<PuzzleEventType>.Of(PuzzleEventType.Restarted)
: None<PuzzleEventType>.New();
_solved = value;
type.Match(some: OnPuzzleEvent);
}
}
private bool _solved;
private void OnPuzzleEvent(PuzzleEventType type)
{
Logger.Log($"{Module} has been {type}", LogType.PuzzleFlow);
PuzzleEvent?.Invoke(Module, type);
}
public override void SetModule(Module module)
{
if (module is PuzzleModule puzzleModule)
{
Module = puzzleModule;
}
else
{
throw new Exception("Tried to set wrong type of module.");
}
}
[Button(enabledMode: EButtonEnableMode.Playmode)]
public void Solve()
{
Solved = true;
}
[Button(enabledMode: EButtonEnableMode.Playmode)]
public void Restart()
{
Solved = false;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 265ea1efb38042b282ea67c50ac3e878
timeCreated: 1668180832

View File

@@ -14,6 +14,7 @@ namespace Escape_Room_Engine.Engine.Scripts
private readonly List<Space> _spaces = new(); private readonly List<Space> _spaces = new();
private readonly List<PuzzleModule> _puzzles = new(); private readonly List<PuzzleModule> _puzzles = new();
private readonly List<DoorModule> _doors = new();
internal Room(Passage entrance) internal Room(Passage entrance)
{ {
@@ -26,12 +27,6 @@ namespace Escape_Room_Engine.Engine.Scripts
exit = spaceExit; exit = spaceExit;
} }
internal void AddPuzzle(PuzzleModule puzzle)
{
_puzzles.Add(puzzle);
puzzle.PuzzleEvent += OnPuzzleEvent;
}
/// <summary> /// <summary>
/// Solves all puzzles in this room. /// Solves all puzzles in this room.
/// </summary> /// </summary>
@@ -39,20 +34,40 @@ namespace Escape_Room_Engine.Engine.Scripts
{ {
Logger.Log($"Skipping {this}...", LogType.PuzzleFlow); Logger.Log($"Skipping {this}...", LogType.PuzzleFlow);
_puzzles.ForEach(puzzle => puzzle.Solve()); _puzzles.ForEach(puzzle => puzzle.State.Solve());
}
internal void AddPuzzle(PuzzleModule puzzle)
{
_puzzles.Add(puzzle);
puzzle.State.PuzzleEvent += OnPuzzleEvent;
} }
private void OnPuzzleEvent(PuzzleModule puzzle, PuzzleEventType type) private void OnPuzzleEvent(PuzzleModule puzzle, PuzzleEventType type)
{ {
if (type == PuzzleEventType.Solved) if (type == PuzzleEventType.Solved)
{ {
if (_puzzles.All(p => p.Solved)) if (_puzzles.All(p => p.State.Solved))
{ {
exit.fromOut.Unlock(); exit.fromOut.State.Unlock();
} }
} }
} }
internal void AddDoor(DoorModule door)
{
_doors.Add(door);
door.State.DoorEvent += OnDoorEvent;
}
private void OnDoorEvent(DoorModule door, DoorEventType type)
{
if (type == DoorEventType.Unlocked && door.Equals(exit.fromOut))
{
Engine.DefaultEngine.GenerateRoom();
}
}
internal void InstantiateRoom(Transform parent, string name) internal void InstantiateRoom(Transform parent, string name)
{ {
roomObject = new GameObject($"Room {name}"); roomObject = new GameObject($"Room {name}");

View File

@@ -15,13 +15,13 @@ namespace Escape_Room_Engine.Engine.Scripts
/// </summary> /// </summary>
internal readonly Dimensions rrDimensions; internal readonly Dimensions rrDimensions;
internal List<Module> Modules { get; } = new(2); internal List<Module> Modules { get; } = new(2);
internal readonly Room room;
private GameObject _spaceObject, _spaceTiles; private GameObject _spaceObject, _spaceTiles;
private readonly Room _room;
internal Space(Room room, Passage entrance) internal Space(Room room, Passage entrance)
{ {
_room = room; this.room = room;
rrDimensions = GenerateSpaceDimensions( rrDimensions = GenerateSpaceDimensions(
entrance, entrance,
Engine.DefaultEngine.config.minRoomSize, Engine.DefaultEngine.config.minRoomSize,
@@ -36,11 +36,6 @@ namespace Escape_Room_Engine.Engine.Scripts
internal void AddModule(Module module) internal void AddModule(Module module)
{ {
Modules.Add(module); Modules.Add(module);
if (module is PuzzleModule puzzleModule)
{
_room.AddPuzzle(puzzleModule);
}
} }
internal bool AddModuleWithRequirements(Module module) internal bool AddModuleWithRequirements(Module module)