From ff01a700bdfe4f2c12b9dd7c52d7b10d9bbcd007 Mon Sep 17 00:00:00 2001 From: milan Date: Thu, 29 Dec 2022 16:16:49 +0100 Subject: [PATCH] comment pass --- Assets/Desert/Runtime/Button.cs | 24 +++++++++--- Assets/Desert/Runtime/Crystal.cs | 13 ++++++- Assets/Desert/Runtime/Dispenser/Dispenser.cs | 8 ++++ .../Runtime/Dispenser/DispenserLights.cs | 5 ++- Assets/Desert/Runtime/Emission.cs | 14 ++++++- Assets/Desert/Runtime/HoloButton.cs | 3 ++ Assets/Desert/Runtime/Hoop.cs | 5 +++ Assets/Desert/Runtime/Portal/DesertPortal.cs | 3 ++ Assets/Desert/Runtime/Puzzle A/Ball.cs | 9 ++++- Assets/Desert/Runtime/Puzzle A/Ring.cs | 12 +++++- Assets/Desert/Runtime/Puzzle A/Symbol.cs | 13 ++++++- .../Desert/Runtime/Puzzle A/SymbolButton.cs | 8 +++- Assets/Desert/Runtime/Puzzle A/Terminal.cs | 30 ++++++++++----- Assets/Desert/Runtime/Puzzle B/PuzzleB.cs | 9 ++++- Assets/Desert/Runtime/Puzzle B/Rotator.cs | 11 +++++- Assets/Desert/Runtime/Puzzle C/Hole.cs | 4 ++ Assets/Desert/Runtime/Puzzle C/Holes.cs | 4 ++ Assets/Engine/Runtime/Editor/EngineEditor.cs | 3 ++ Assets/Engine/Runtime/Engine.cs | 18 +++++++++ Assets/Engine/Runtime/EngineTheme.cs | 6 +++ Assets/Engine/Runtime/Measurements/Measure.cs | 38 +++++++++++++++++++ .../Engine/Runtime/Measurements/PlanResult.cs | 12 ++++++ Assets/Engine/Runtime/Measurements/Puzzle.cs | 15 ++++++++ .../Runtime/Measurements/PuzzleMeasurement.cs | 12 ++++++ .../Runtime/Measurements/PuzzleStorage.cs | 31 +++++++++++++++ Assets/Engine/Runtime/Measurements/Session.cs | 17 +++++++++ .../Runtime/Modules/CyclicStepPuzzle.cs | 7 +++- Assets/Engine/Runtime/Modules/DoorModule.cs | 10 +++++ .../Runtime/Modules/DoorModuleDescription.cs | 3 ++ Assets/Engine/Runtime/Modules/DoorState.cs | 9 +++++ Assets/Engine/Runtime/Modules/Module.cs | 3 ++ .../Runtime/Modules/ModuleDescription.cs | 4 ++ Assets/Engine/Runtime/Modules/ModuleState.cs | 4 ++ Assets/Engine/Runtime/Modules/ModuleType.cs | 3 ++ Assets/Engine/Runtime/Modules/PuzzleModule.cs | 7 ++++ .../Modules/PuzzleModuleDescription.cs | 8 ++++ Assets/Engine/Runtime/Modules/PuzzleState.cs | 17 ++++++++- Assets/Engine/Runtime/Modules/Spawn.cs | 3 ++ Assets/Engine/Runtime/Modules/StatePuzzle.cs | 13 ++++++- Assets/Engine/Runtime/Modules/StepPuzzle.cs | 6 ++- Assets/Engine/Runtime/Orientation.cs | 12 ++++++ Assets/Engine/Runtime/Passage.cs | 18 +++++++++ Assets/Engine/Runtime/Placement.cs | 6 +++ .../Runtime/Requirements/FaceSpaceCenter.cs | 3 ++ .../Runtime/Requirements/LockOrientation.cs | 3 ++ .../Engine/Runtime/Requirements/NoOverlap.cs | 3 ++ .../Requirements/PlaceAlongSpaceEdges.cs | 3 ++ .../Runtime/Requirements/PlaceAnywhere.cs | 3 ++ .../Requirements/PlaceWithRelatedModule.cs | 3 ++ .../Requirements/PlacementRequirement.cs | 3 ++ .../Requirements/PreconditionRequirement.cs | 3 ++ .../Runtime/Requirements/RelatedModule.cs | 3 ++ .../Runtime/Requirements/Requirement.cs | 3 ++ Assets/Engine/Runtime/Room.cs | 6 +++ Assets/Engine/Runtime/Space.cs | 6 +++ Assets/Engine/Runtime/SpaceTile.cs | 3 ++ Assets/Engine/Runtime/UI/GameControl.cs | 27 ++++++++++++- Assets/Engine/Runtime/UI/PauseButton.cs | 3 ++ Assets/Engine/Runtime/UI/PuzzlePlan.cs | 7 +++- Assets/Engine/Runtime/UI/PuzzlePlanEntry.cs | 4 +- Assets/Engine/Runtime/Utilities/Backtrack.cs | 7 +++- .../Runtime/Utilities/DisablePicking.cs | 5 ++- .../Engine/Runtime/Utilities/DynamicColor.cs | 3 ++ Assets/Engine/Runtime/Utilities/Logger.cs | 25 ++++++------ .../Engine/Runtime/Utilities/Probability.cs | 38 ++++++++++++++++++- Assets/Engine/Runtime/Utilities/Range.cs | 9 +++++ Assets/Engine/Runtime/Utilities/Utilities.cs | 12 ++++++ Assets/Portal/Runtime/Portal.cs | 15 ++++++++ Assets/Portal/Runtime/PortalCamera.cs | 2 +- Assets/Portal/Runtime/PortalCollider.cs | 3 ++ Assets/Portal/Runtime/PortalDriver.cs | 3 ++ Assets/Portal/Runtime/PortalDriverClone.cs | 3 ++ Assets/Test Assets/BacktrackingTest.cs | 3 ++ Assets/Test Assets/ProbabilityTest.cs | 3 ++ Assets/VR/Runtime/Player.cs | 22 +++++------ 75 files changed, 634 insertions(+), 65 deletions(-) diff --git a/Assets/Desert/Runtime/Button.cs b/Assets/Desert/Runtime/Button.cs index b741816..901d9d3 100644 --- a/Assets/Desert/Runtime/Button.cs +++ b/Assets/Desert/Runtime/Button.cs @@ -1,4 +1,5 @@ using System; +using JetBrains.Annotations; using NaughtyAttributes; using UnityEngine; using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger; @@ -30,10 +31,16 @@ namespace EscapeRoomEngine.Desert.Runtime public delegate void ButtonEventHandler(Button source, ButtonEventType e); + /// + /// A general component for buttons that handles button events. + /// public class Button : MonoBehaviour { public event ButtonEventHandler ButtonEvent; + /// + /// Whether this button accepts input. + /// [ShowNativeProperty] protected bool Active { @@ -50,6 +57,9 @@ namespace EscapeRoomEngine.Desert.Runtime } } + /// + /// Whether this button is currently pressed. + /// [ShowNativeProperty] protected bool Pressed { @@ -88,11 +98,15 @@ namespace EscapeRoomEngine.Desert.Runtime #region Debug Buttons - [Button(enabledMode: EButtonEnableMode.Playmode)] public void Enable() => Active = true; - [Button(enabledMode: EButtonEnableMode.Playmode)] public void Disable() => Active = false; - [Button(enabledMode: EButtonEnableMode.Playmode)] public void Press() => Pressed = true; - [Button(enabledMode: EButtonEnableMode.Playmode)] public void Release() => Pressed = false; - + [Button(enabledMode: EButtonEnableMode.Playmode)] + public void Enable() => Active = true; + [Button(enabledMode: EButtonEnableMode.Playmode)] + public void Disable() => Active = false; + [Button(enabledMode: EButtonEnableMode.Playmode)] + public void Press() => Pressed = true; + [Button(enabledMode: EButtonEnableMode.Playmode)] + public void Release() => Pressed = false; + [UsedImplicitly] [Button(enabledMode: EButtonEnableMode.Playmode)] public void PressAndRelease() { diff --git a/Assets/Desert/Runtime/Crystal.cs b/Assets/Desert/Runtime/Crystal.cs index c2400f4..d46ab39 100644 --- a/Assets/Desert/Runtime/Crystal.cs +++ b/Assets/Desert/Runtime/Crystal.cs @@ -4,11 +4,19 @@ using UnityEngine; namespace EscapeRoomEngine.Desert.Runtime { + /// + /// A rotating crystal that can change colour. + /// [RequireComponent(typeof(Emission))] public class Crystal : MonoBehaviour { - [Required] public Light crystalLight; + [Required] + [BoxGroup("Internal")] + public Light crystalLight; + /// + /// Turns the crystal light on or off. + /// public bool Active { set @@ -18,6 +26,9 @@ namespace EscapeRoomEngine.Desert.Runtime } } + /// + /// The crystal light and emission colours. + /// public DynamicColor Color { set diff --git a/Assets/Desert/Runtime/Dispenser/Dispenser.cs b/Assets/Desert/Runtime/Dispenser/Dispenser.cs index c1d4966..a90405c 100644 --- a/Assets/Desert/Runtime/Dispenser/Dispenser.cs +++ b/Assets/Desert/Runtime/Dispenser/Dispenser.cs @@ -6,13 +6,18 @@ using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace EscapeRoomEngine.Desert.Runtime.Dispenser { + /// + /// The main component for the dispenser module. + /// [SelectionBase] [RequireComponent(typeof(Animator), typeof(Emission))] public class Dispenser : ModuleState { private static readonly int Open = Animator.StringToHash("Open"); + [Tooltip("The object this dispenser should produce.")] public Transform dispensable; + [Tooltip("The time in seconds to wait until another object can be produced.")] [SerializeField] [Min(0)] private float cooldown; [BoxGroup("Internal")] [SerializeField] @@ -20,6 +25,9 @@ namespace EscapeRoomEngine.Desert.Runtime.Dispenser [BoxGroup("Internal")] [SerializeField] private Button dispenseButton; + /// + /// The dispenser does not produce any more objects when it is solved and changes colour. + /// public bool Solved { set diff --git a/Assets/Desert/Runtime/Dispenser/DispenserLights.cs b/Assets/Desert/Runtime/Dispenser/DispenserLights.cs index a58154b..b8425b6 100644 --- a/Assets/Desert/Runtime/Dispenser/DispenserLights.cs +++ b/Assets/Desert/Runtime/Dispenser/DispenserLights.cs @@ -10,8 +10,12 @@ namespace EscapeRoomEngine.Desert.Runtime.Dispenser public bool[] lights; } + /// + /// This component controls the grid of lights on the dispenser. + /// public class DispenserLights : MonoBehaviour { + [Tooltip("Control the pattern of lights on a dispenser.")] [SerializeField] private DispenserLightRow[] lights; [BoxGroup("Internal")] [SerializeField] @@ -23,7 +27,6 @@ namespace EscapeRoomEngine.Desert.Runtime.Dispenser private void Start() { - var position = transform.localPosition; for (var y = 0; y < gridDimensions.y; y++) { var row = lights[y].lights; diff --git a/Assets/Desert/Runtime/Emission.cs b/Assets/Desert/Runtime/Emission.cs index e002ef8..0533af7 100644 --- a/Assets/Desert/Runtime/Emission.cs +++ b/Assets/Desert/Runtime/Emission.cs @@ -3,13 +3,23 @@ using UnityEngine; namespace EscapeRoomEngine.Desert.Runtime { + /// + /// A general component for controlling the emission of an object. + /// public class Emission : MonoBehaviour { private static readonly int EmissionColorNameID = Shader.PropertyToID("_EmissionColor"); + [Tooltip("The colour of the emission.")] + [ColorUsage(false, true)] + public Color color; + [BoxGroup("Internal")] [Required] + public MeshRenderer emissionRenderer; + + /// + /// Whether the emission is on. + /// internal bool active; - [ColorUsage(false, true)] public Color color; - [BoxGroup("Internal")] [Required] public MeshRenderer emissionRenderer; private bool _previousActive; private Color _previousColor; diff --git a/Assets/Desert/Runtime/HoloButton.cs b/Assets/Desert/Runtime/HoloButton.cs index f848355..16e4d92 100644 --- a/Assets/Desert/Runtime/HoloButton.cs +++ b/Assets/Desert/Runtime/HoloButton.cs @@ -3,6 +3,9 @@ using UnityEngine; namespace EscapeRoomEngine.Desert.Runtime { + /// + /// A holographic that changes its colour when it is pressed. + /// public class HoloButton : Button { private static readonly int FresnelColor = Shader.PropertyToID("_FresnelColor"); diff --git a/Assets/Desert/Runtime/Hoop.cs b/Assets/Desert/Runtime/Hoop.cs index cb147bf..e1016e9 100644 --- a/Assets/Desert/Runtime/Hoop.cs +++ b/Assets/Desert/Runtime/Hoop.cs @@ -8,9 +8,13 @@ using UnityEngine; namespace EscapeRoomEngine.Desert.Runtime { + /// + /// The main component for the orb throwing module. + /// [RequireComponent(typeof(Collider))] public class Hoop : StatePuzzle { + [Tooltip("How long to wait in seconds until the state is updated. Orbs that do not stay in the hoop should not be counted.")] public float updateDelay; [BoxGroup("Internal")] [SerializeField] private List rings; @@ -84,6 +88,7 @@ namespace EscapeRoomEngine.Desert.Runtime { base.SetModule(module); + // The hoop requires a related dispenser module var firstRelatedModule = Module.relatedModules[0]; if (firstRelatedModule.State is Dispenser.Dispenser dispenser) { diff --git a/Assets/Desert/Runtime/Portal/DesertPortal.cs b/Assets/Desert/Runtime/Portal/DesertPortal.cs index 33e20a8..8aee50e 100644 --- a/Assets/Desert/Runtime/Portal/DesertPortal.cs +++ b/Assets/Desert/Runtime/Portal/DesertPortal.cs @@ -3,6 +3,9 @@ using UnityEngine; namespace EscapeRoomEngine.Desert.Runtime.Portal { + /// + /// The desert theme includes its own version of a portal that changes colour when it is unlocked. + /// [RequireComponent(typeof(Emission))] public class DesertPortal : EscapeRoomEngine.Portal.Runtime.Portal { diff --git a/Assets/Desert/Runtime/Puzzle A/Ball.cs b/Assets/Desert/Runtime/Puzzle A/Ball.cs index 90415df..893bbca 100644 --- a/Assets/Desert/Runtime/Puzzle A/Ball.cs +++ b/Assets/Desert/Runtime/Puzzle A/Ball.cs @@ -3,10 +3,15 @@ using NaughtyAttributes; namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A { + /// + /// The main component for the symbol ball module. + /// public class Ball : ModuleState { - [BoxGroup("Internal")] [Required] public Emission statusLight; - [BoxGroup("Internal")] [Required] public Ring ring; + [BoxGroup("Internal")] [Required] + public Emission statusLight; + [BoxGroup("Internal")] [Required] + public Ring ring; public bool StatusLight { diff --git a/Assets/Desert/Runtime/Puzzle A/Ring.cs b/Assets/Desert/Runtime/Puzzle A/Ring.cs index ae15399..4bf1249 100644 --- a/Assets/Desert/Runtime/Puzzle A/Ring.cs +++ b/Assets/Desert/Runtime/Puzzle A/Ring.cs @@ -6,12 +6,20 @@ using UnityEngine; namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A { + /// + /// The rotating ring in the symbol ball module. + /// public class Ring : MonoBehaviour { + [Tooltip("Whether the ring is rotating.")] public bool rotating = true; + [Tooltip("The current angle of the rotation.")] public float rotationAngle; - [MinMaxSlider(-180, 180)] public Vector2 activeRange; - [BoxGroup("Internal")] [Required] public Crystal crystal; + [Tooltip("The range in degrees from the front of the module where a symbol should be lit up.")] + [MinMaxSlider(-180, 180)] + public Vector2 activeRange; + [BoxGroup("Internal")] [Required] + public Crystal crystal; [BoxGroup("Internal")] [ValidateInput("SymbolCount", "Must have same amount of symbols and slots.")] public List symbols; diff --git a/Assets/Desert/Runtime/Puzzle A/Symbol.cs b/Assets/Desert/Runtime/Puzzle A/Symbol.cs index ab9f4ed..54735f5 100644 --- a/Assets/Desert/Runtime/Puzzle A/Symbol.cs +++ b/Assets/Desert/Runtime/Puzzle A/Symbol.cs @@ -1,4 +1,5 @@ using System; +using NaughtyAttributes; using UnityEngine; using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger; using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; @@ -27,13 +28,23 @@ namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A public delegate void SymbolEventHandler(SymbolEventType e); + /// + /// The main component for the symbols on the symbol ring module. + /// [RequireComponent(typeof(Emission))] public class Symbol : MonoBehaviour { - public int symbolNumber, symbolPosition; + [Tooltip("The number of the symbol in the puzzle solution.")] + public int symbolNumber; + [BoxGroup("Internal")] + public int symbolPosition; + [BoxGroup("Internal")] public float anglePosition; public event SymbolEventHandler SymbolEvent; + /// + /// Whether the symbol is lit up. This is controlled by the . + /// public bool Active { set diff --git a/Assets/Desert/Runtime/Puzzle A/SymbolButton.cs b/Assets/Desert/Runtime/Puzzle A/SymbolButton.cs index 1fe65aa..fc9683c 100644 --- a/Assets/Desert/Runtime/Puzzle A/SymbolButton.cs +++ b/Assets/Desert/Runtime/Puzzle A/SymbolButton.cs @@ -1,7 +1,13 @@ -namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A +using UnityEngine; + +namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A { + /// + /// A that includes the number of its assigned symbol. + /// public class SymbolButton : HoloButton { + [Tooltip("The number of the symbol assigned to this button.")] public int symbolNumber; } } \ No newline at end of file diff --git a/Assets/Desert/Runtime/Puzzle A/Terminal.cs b/Assets/Desert/Runtime/Puzzle A/Terminal.cs index ee56c22..ed88011 100644 --- a/Assets/Desert/Runtime/Puzzle A/Terminal.cs +++ b/Assets/Desert/Runtime/Puzzle A/Terminal.cs @@ -10,12 +10,16 @@ using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A { + /// + /// The main component for the terminal module. + /// [RequireComponent(typeof(Animator))] public class Terminal : CyclicStepPuzzle { private static readonly int LightFlash = Animator.StringToHash("Light Flash"); - [BoxGroup("Internal")] [Required] public Emission terminalLight; + [BoxGroup("Internal")] [Required] + public Emission terminalLight; [BoxGroup("Internal")] [ValidateInput("SymbolCount", "Must have same amount of symbols and slots.")] public List symbols; @@ -82,6 +86,7 @@ namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A { base.SetModule(module); + // The terminal requires a related symbol ball module var firstRelatedModule = Module.relatedModules[0]; if (firstRelatedModule.State is Ball ball) { @@ -95,15 +100,15 @@ namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A TurnOnLights(); } - // required in animation - [UsedImplicitly] internal void TurnOnLights() + [UsedImplicitly] // required in animation + internal void TurnOnLights() { terminalLight.active = true; _ball.StatusLight = true; } - // required in animation - [UsedImplicitly] internal void TurnOffLights() + [UsedImplicitly] // required in animation + internal void TurnOffLights() { terminalLight.active = false; _ball.StatusLight = false; @@ -131,12 +136,19 @@ namespace EscapeRoomEngine.Desert.Runtime.Puzzle_A #region Debug Buttons - [Button(enabledMode: EButtonEnableMode.Playmode)] public void PressSymbol0() => PressedSymbol(0); - [Button(enabledMode: EButtonEnableMode.Playmode)] public void PressSymbol1() => PressedSymbol(1); - [Button(enabledMode: EButtonEnableMode.Playmode)] public void PressSymbol2() => PressedSymbol(2); + [UsedImplicitly] + [Button(enabledMode: EButtonEnableMode.Playmode)] + public void PressSymbol0() => PressedSymbol(0); + [UsedImplicitly] + [Button(enabledMode: EButtonEnableMode.Playmode)] + public void PressSymbol1() => PressedSymbol(1); + [UsedImplicitly] + [Button(enabledMode: EButtonEnableMode.Playmode)] + public void PressSymbol2() => PressedSymbol(2); #endregion - [UsedImplicitly] private bool SymbolCount(List list) => list.Count == symbolSlots.Count; + [UsedImplicitly] // used for field validation + private bool SymbolCount(List list) => list.Count == symbolSlots.Count; } } \ No newline at end of file diff --git a/Assets/Desert/Runtime/Puzzle B/PuzzleB.cs b/Assets/Desert/Runtime/Puzzle B/PuzzleB.cs index 4b65a47..e696ff9 100644 --- a/Assets/Desert/Runtime/Puzzle B/PuzzleB.cs +++ b/Assets/Desert/Runtime/Puzzle B/PuzzleB.cs @@ -16,8 +16,12 @@ namespace EscapeRoomEngine.Desert.Runtime.Puzzle_B public List stateIndices; } + /// + /// The main component for the hexagon module. + /// public class PuzzleB : StatePuzzle { + [Tooltip("How many seconds the buttons should be disabled until another input is accepted.")] [SerializeField] [Min(0)] private float buttonCooldown; [ValidateInput("CorrectRotatorCount")] @@ -86,6 +90,9 @@ namespace EscapeRoomEngine.Desert.Runtime.Puzzle_B } } + /// + /// Switch all rotators specified by a given action. + /// private void Switch(ButtonAction action) { for (var i = 0; i < action.stateIndices.Count; i++) @@ -99,7 +106,7 @@ namespace EscapeRoomEngine.Desert.Runtime.Puzzle_B } } - [UsedImplicitly] + [UsedImplicitly] // used for field validation private bool CorrectRotatorCount(List list) => list != null && list.Count == stateCount; } } \ No newline at end of file diff --git a/Assets/Desert/Runtime/Puzzle B/Rotator.cs b/Assets/Desert/Runtime/Puzzle B/Rotator.cs index aab5090..9fd3636 100644 --- a/Assets/Desert/Runtime/Puzzle B/Rotator.cs +++ b/Assets/Desert/Runtime/Puzzle B/Rotator.cs @@ -3,11 +3,18 @@ using UnityEngine; namespace EscapeRoomEngine.Desert.Runtime.Puzzle_B { + /// + /// The rotator component used by the hexagon module. + /// [RequireComponent(typeof(Emission))] public class Rotator : MonoBehaviour { - [Range(0, 359)] public int angle; - [Range(0, 1)] public float speed; + [Tooltip("The angle this rotator should rotate towards.")] + [Range(0, 359)] + public int angle; + [Tooltip("How quickly to rotate towards the target angle.")] + [Range(0, 1)] + public float speed; public Emission Emission { get; private set; } diff --git a/Assets/Desert/Runtime/Puzzle C/Hole.cs b/Assets/Desert/Runtime/Puzzle C/Hole.cs index c01dda6..caa7c06 100644 --- a/Assets/Desert/Runtime/Puzzle C/Hole.cs +++ b/Assets/Desert/Runtime/Puzzle C/Hole.cs @@ -3,9 +3,13 @@ using UnityEngine; namespace EscapeRoomEngine.Desert.Runtime.Puzzle_C { + /// + /// A hole used in the module. + /// [RequireComponent(typeof(Emission), typeof(Collider))] public class Hole : Button { + [Tooltip("The number of this hole, starting from the bottom left.")] [Min(0)] public int number; diff --git a/Assets/Desert/Runtime/Puzzle C/Holes.cs b/Assets/Desert/Runtime/Puzzle C/Holes.cs index f17fece..726c317 100644 --- a/Assets/Desert/Runtime/Puzzle C/Holes.cs +++ b/Assets/Desert/Runtime/Puzzle C/Holes.cs @@ -6,6 +6,9 @@ using UnityEngine; namespace EscapeRoomEngine.Desert.Runtime.Puzzle_C { + /// + /// The main component for the orb grid module. + /// public class Holes : StatePuzzle { [BoxGroup("Internal")] [SerializeField] @@ -75,6 +78,7 @@ namespace EscapeRoomEngine.Desert.Runtime.Puzzle_C { base.SetModule(module); + // The holes require a related dispenser module var firstRelatedModule = Module.relatedModules[0]; if (firstRelatedModule.State is Dispenser.Dispenser dispenser) { diff --git a/Assets/Engine/Runtime/Editor/EngineEditor.cs b/Assets/Engine/Runtime/Editor/EngineEditor.cs index 3db326e..3e8a1d3 100644 --- a/Assets/Engine/Runtime/Editor/EngineEditor.cs +++ b/Assets/Engine/Runtime/Editor/EngineEditor.cs @@ -5,6 +5,9 @@ using UnityEngine.UIElements; namespace EscapeRoomEngine.Engine.Runtime.Editor { #if UNITY_EDITOR + /// + /// An used to test the . + /// public class EngineEditor : EditorWindow { private bool _registeredUpdateEvent; diff --git a/Assets/Engine/Runtime/Engine.cs b/Assets/Engine/Runtime/Engine.cs index f6b3270..dfcbf1e 100644 --- a/Assets/Engine/Runtime/Engine.cs +++ b/Assets/Engine/Runtime/Engine.cs @@ -11,9 +11,18 @@ using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace EscapeRoomEngine.Engine.Runtime { + /// + /// The engine controls the whole escape room. It generates rooms and manages the puzzle plan. + /// public class Engine : MonoBehaviour { + /// + /// The active theme of the engine. + /// public static EngineTheme Theme => Instance.theme; + /// + /// The active instance of the engine. + /// public static Engine Instance { get; private set; } public delegate void UpdateUIHandler(); @@ -23,11 +32,16 @@ namespace EscapeRoomEngine.Engine.Runtime public int maxSpaceGenerationTries = 1000; [Tooltip("The engine will try to generate a room that takes approximately this many seconds to complete.")] public float initialTargetTime = 10 * 60; + [Tooltip("The offset each room will have from the previous one.")] public Vector3 roomOffset = new(0, 1000, 0); + [Tooltip("The theme of the engine that decides the available puzzles, doors and more.")] [Required] public EngineTheme theme; public int NumberOfRooms => _rooms.Count; public IOption CurrentRoom => NumberOfRooms > 0 ? Some.Of(_rooms[^1]) : None.New(); + /// + /// The currendly estimated time for the player to finish the experience. + /// public float EstimatedTimeRemaining { get; private set; } private readonly List _rooms = new(); @@ -169,6 +183,10 @@ namespace EscapeRoomEngine.Engine.Runtime GameControl.Instance.PlannedPuzzles = _plannedPuzzles; } + /// + /// Hide or destroy the room two rooms ago. The actual previous room is kept for the player to be able to backtrack one room. + /// + /// public void HidePreviousRoom(bool destroy = true) { if (NumberOfRooms > 2) diff --git a/Assets/Engine/Runtime/EngineTheme.cs b/Assets/Engine/Runtime/EngineTheme.cs index 5979b7d..7d4b506 100644 --- a/Assets/Engine/Runtime/EngineTheme.cs +++ b/Assets/Engine/Runtime/EngineTheme.cs @@ -7,6 +7,9 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime { + /// + /// An engine theme decides the room size, look and available modules for the engine. + /// [CreateAssetMenu(menuName = "Engine Theme")] public class EngineTheme : ScriptableObject { @@ -23,9 +26,11 @@ namespace EscapeRoomEngine.Engine.Runtime #region Theme [BoxGroup("Theme")] [Required] + [Tooltip("The tile that rooms are generated from.")] public SpaceTile spaceTile; [BoxGroup("Theme")] + [Tooltip("The environment that is placed around every generated room.")] public GameObject environment; [BoxGroup("Theme")] @@ -39,6 +44,7 @@ namespace EscapeRoomEngine.Engine.Runtime public DoorModuleDescription spawnDoor; [BoxGroup("Doors")] [ValidateInput("IsNotEmpty", "At least one exit door type is required.")] + [Tooltip("The types of exit doors this theme provides. Entrance doors are connected to the exit doors and don't need to be specified here.")] public List exitDoorTypes; #endregion diff --git a/Assets/Engine/Runtime/Measurements/Measure.cs b/Assets/Engine/Runtime/Measurements/Measure.cs index a396ea6..a6564f7 100644 --- a/Assets/Engine/Runtime/Measurements/Measure.cs +++ b/Assets/Engine/Runtime/Measurements/Measure.cs @@ -9,6 +9,9 @@ using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace EscapeRoomEngine.Engine.Runtime.Measurements { + /// + /// This class is the main way to interact with measurements. + /// public static class Measure { /// @@ -19,20 +22,46 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements private static Dictionary _runningMeasurements; private static Session _currentSession; + /// + /// The average time to solve a specific puzzle. + /// public static float AverageTime(PuzzleModuleDescription puzzle) => PuzzleStorage.Instance.Load(puzzle).AverageTimeToSolve; + /// + /// The average time to solve a group of puzzles. + /// public static float AverageTime(IEnumerable puzzles) => puzzles.Sum(AverageTime); + /// + /// The average time to solve a specific room. + /// + /// This only counts puzzles already placed in a room. public static float AverageTime(Room room) => room.puzzles.Sum(puzzle => AverageTime((PuzzleModuleDescription)puzzle.description)); + /// + /// Estimate the time a specific puzzle will take to be solved by the current player. + /// public static float EstimateTime(PuzzleModuleDescription puzzle) => PuzzleStorage.Instance.Load(puzzle).EstimateTimeToSolve(SessionPercentile()); + /// + /// Estimate the time a group of puzzles will take to be solved by the current player. + /// public static float EstimateTime(IEnumerable puzzles) => puzzles.Sum(EstimateTime); + /// + /// Estimate the time a room will take to be solved by the current player. + /// + /// This only counts puzzles already placed in a room. public static float EstimateTime(Room room) => room.puzzles.Sum(puzzle => EstimateTime((PuzzleModuleDescription)puzzle.description)); + /// + /// The estimated percentile the current player is placed in. + /// public static float SessionPercentile() => _currentSession?.MeanPercentile ?? 0.5f; + /// + /// Start counting the time to solve a specific puzzle. + /// public static void StartMeasuring(PuzzleModuleDescription puzzle) { _runningMeasurements[puzzle.Id] = new PuzzleMeasurement @@ -44,6 +73,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements Logger.Log($"Started measuring {puzzle}", LogType.Measuring); } + /// + /// A puzzle has been solved and the measurement should be stopped. This will also store the finished measurement in the database. + /// public static void Solve(PuzzleModuleDescription puzzle) { if (_currentSession == null) @@ -62,6 +94,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements Logger.Log($"Solved {puzzle} with measurement {measurement}", LogType.Measuring); } + /// + /// Start a new session and place the current player at the 50th percentile. + /// public static void StartSession() { _currentSession = new Session(); @@ -75,6 +110,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements Logger.Log($"Started {_currentSession}", LogType.Measuring); } + /// + /// End a session and store it in the database. + /// public static void EndSession(float time) { if (Store) diff --git a/Assets/Engine/Runtime/Measurements/PlanResult.cs b/Assets/Engine/Runtime/Measurements/PlanResult.cs index 31fae43..9fb9e34 100644 --- a/Assets/Engine/Runtime/Measurements/PlanResult.cs +++ b/Assets/Engine/Runtime/Measurements/PlanResult.cs @@ -3,10 +3,22 @@ using Realms; namespace EscapeRoomEngine.Engine.Runtime.Measurements { + /// + /// The target and estimated time, along with the percentile since the last section, that will be stored in the database. + /// public class PlanResult : EmbeddedObject { + /// + /// The target time set by the game master when this section ended. + /// public float TargetTime { get; set; } + /// + /// The percentile of the current player during this section. + /// public float SectionPercentile { get; set; } + /// + /// The estimated time to complete the whole puzzle plan when this section ended. + /// public float TimeEstimation { get; set; } [UsedImplicitly] diff --git a/Assets/Engine/Runtime/Measurements/Puzzle.cs b/Assets/Engine/Runtime/Measurements/Puzzle.cs index d9a2b3f..cd0edd8 100644 --- a/Assets/Engine/Runtime/Measurements/Puzzle.cs +++ b/Assets/Engine/Runtime/Measurements/Puzzle.cs @@ -8,15 +8,30 @@ using Realms; namespace EscapeRoomEngine.Engine.Runtime.Measurements { + /// + /// The representation of a specific puzzle in the database. This includes all measurements for this puzzle. + /// [SuppressMessage("ReSharper", "UnassignedGetOnlyAutoProperty")] public class Puzzle : RealmObject { [PrimaryKey] public int ID { get; set; } + /// + /// All puzzle measurements recorded for this puzzle. + /// public IList Measurements { get; } + /// + /// How much time has been spent on this puzzle in total. This is used to calculate the average time to solve this puzzle. + /// public float TotalTimeSpentOnPuzzle => Measurements.Sum(measurement => measurement.Time); + /// + /// The average time to solve this puzzle using all measurements recorded for it. + /// public float AverageTimeToSolve => Measurements.Count > 0 ? TotalTimeSpentOnPuzzle / Measurements.Count : 0f; + /// + /// The normal distribution of all recorded measurements. + /// public NormalDistribution Distribution => new(TimesAsSamples()); [UsedImplicitly] diff --git a/Assets/Engine/Runtime/Measurements/PuzzleMeasurement.cs b/Assets/Engine/Runtime/Measurements/PuzzleMeasurement.cs index f7c1a76..f592d63 100644 --- a/Assets/Engine/Runtime/Measurements/PuzzleMeasurement.cs +++ b/Assets/Engine/Runtime/Measurements/PuzzleMeasurement.cs @@ -3,11 +3,23 @@ using Realms; namespace EscapeRoomEngine.Engine.Runtime.Measurements { + /// + /// A single measurement, consisting of when a puzzle was started and solved, stored in the database. + /// public class PuzzleMeasurement : EmbeddedObject { + /// + /// The relative time since the engine was initialised of when this puzzle was started. + /// public float TimeStarted { get; set; } + /// + /// The relative time since the engine was initialised of when this puzzle was solved. + /// public float TimeSolved { get; set; } + /// + /// The total time taken to solve this puzzle during this measurement. + /// public float Time => TimeSolved - TimeStarted; public override string ToString() diff --git a/Assets/Engine/Runtime/Measurements/PuzzleStorage.cs b/Assets/Engine/Runtime/Measurements/PuzzleStorage.cs index 15b79a5..65f2810 100644 --- a/Assets/Engine/Runtime/Measurements/PuzzleStorage.cs +++ b/Assets/Engine/Runtime/Measurements/PuzzleStorage.cs @@ -7,12 +7,22 @@ using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace EscapeRoomEngine.Engine.Runtime.Measurements { + /// + /// The storage engine that manages the data in a realm database. + /// public class PuzzleStorage : MonoBehaviour { + /// + /// The schema version must be updated whenever the schema in the database changed. + /// private const int SchemaVersion = 2; + /// + /// The active instance of the storage engine. + /// public static PuzzleStorage Instance { get; private set; } + [Tooltip("The path of the database relative to where the engine stores persistent data.")] [SerializeField] private string databasePath = "measurements.realm"; @@ -20,6 +30,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements private void OnEnable() { + // configure special actions during specific migrations of the database var config = new RealmConfiguration { SchemaVersion = SchemaVersion, @@ -59,6 +70,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements #region Session + /// + /// End a session and store it to the database. + /// public void EndSession(Session session, float time) { session.Time = time; @@ -70,6 +84,10 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements #region Puzzles + /// + /// Create a new puzzle for a specific description and store it in the database. + /// + /// This requires that the puzzle does not yet exist in the database. private Puzzle New(PuzzleModuleDescription puzzle) { Puzzle created = null; @@ -79,10 +97,20 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements return created; } + /// + /// Load a specific puzzle from the database or create it if it wasn't found. + /// private Puzzle LoadOrNew(PuzzleModuleDescription puzzle) => _realm.Find(puzzle.Id) ?? New(puzzle); + /// + /// Load a specific puzzle from the database. + /// + /// The puzzle or null if it wasn't found in the database. public Puzzle Load(PuzzleModuleDescription puzzle) => _realm.Find(puzzle.Id); + /// + /// Delete all records concerning a specific puzzle from the database irreversibly. + /// public void Delete(PuzzleModuleDescription puzzle) { var found = Load(puzzle); @@ -92,6 +120,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements } } + /// + /// End the measurement for a specific puzzle and store it in the database. Also stores the results of the current puzzle plan. + /// public void EndMeasurement(Session session, PuzzleModuleDescription puzzle, PuzzleMeasurement measurement) { var found = LoadOrNew(puzzle); diff --git a/Assets/Engine/Runtime/Measurements/Session.cs b/Assets/Engine/Runtime/Measurements/Session.cs index 198f4db..b9676e1 100644 --- a/Assets/Engine/Runtime/Measurements/Session.cs +++ b/Assets/Engine/Runtime/Measurements/Session.cs @@ -8,16 +8,33 @@ using Realms; namespace EscapeRoomEngine.Engine.Runtime.Measurements { + /// + /// The representation of a session in the database. This stores all plan results during this session and what puzzles were solved. + /// [SuppressMessage("ReSharper", "UnassignedGetOnlyAutoProperty")] public class Session : RealmObject { [PrimaryKey] public ObjectId ID { get; set; } public float Time { get; set; } + /// + /// The plan results for each section during this section. + /// + /// The order of the plan results corresponds with the order of the solved puzzles. public IList PlanResults { get; } + /// + /// The puzzles solved during this session. + /// + /// The order of the solved puzzles corresponds with the order of the plan results. public IList PuzzlesSolved { get; } + /// + /// The section percentiles the current player has been placed in. + /// public IEnumerable Percentiles => PlanResults.Select(result => result.SectionPercentile); + /// + /// The average of all section percentiles. + /// public float MeanPercentile => PlanResults.Count == 0 ? .5f : Probability.Mean(Percentiles.ToArray()); [UsedImplicitly] diff --git a/Assets/Engine/Runtime/Modules/CyclicStepPuzzle.cs b/Assets/Engine/Runtime/Modules/CyclicStepPuzzle.cs index 4497158..22a2490 100644 --- a/Assets/Engine/Runtime/Modules/CyclicStepPuzzle.cs +++ b/Assets/Engine/Runtime/Modules/CyclicStepPuzzle.cs @@ -3,9 +3,14 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Modules { + /// + /// A whose steps are considered a cycle that can be started anywhere and must be stepped through once. + /// public class CyclicStepPuzzle : StepPuzzle { - [BoxGroup("Step Puzzle")] [Min(0)] public int cycleStep; + [Tooltip("The current step in the cycle.")] + [BoxGroup("Step Puzzle")] [Min(0)] + public int cycleStep; protected override void CheckStep(int step) { diff --git a/Assets/Engine/Runtime/Modules/DoorModule.cs b/Assets/Engine/Runtime/Modules/DoorModule.cs index ed48896..6367352 100644 --- a/Assets/Engine/Runtime/Modules/DoorModule.cs +++ b/Assets/Engine/Runtime/Modules/DoorModule.cs @@ -9,13 +9,22 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules Entrance = ModuleType.DoorEntrance, Exit = ModuleType.DoorExit } + /// + /// The main component of any door module. + /// [Serializable] public class DoorModule : Module { public bool IsEntrance => IsType((ModuleType)DoorType.Entrance); public bool IsExit => IsType((ModuleType)DoorType.Exit); + /// + /// The module state of this door as a . + /// public DoorState DoorState => DoorState.FromState(State); + /// + /// The module state of the connected door as a . + /// public DoorState ConnectedDoorState => Passage.Other(this).DoorState; /// @@ -47,6 +56,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules { base.InstantiateModule(parent); + // the room needs to know about this door space.room.AddDoor(this); } diff --git a/Assets/Engine/Runtime/Modules/DoorModuleDescription.cs b/Assets/Engine/Runtime/Modules/DoorModuleDescription.cs index 3648c0b..88937ec 100644 --- a/Assets/Engine/Runtime/Modules/DoorModuleDescription.cs +++ b/Assets/Engine/Runtime/Modules/DoorModuleDescription.cs @@ -2,6 +2,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules { + /// + /// The for a . Includes the description of the connected door. + /// [CreateAssetMenu(menuName = "Modules/Door")] public class DoorModuleDescription : ModuleDescription { diff --git a/Assets/Engine/Runtime/Modules/DoorState.cs b/Assets/Engine/Runtime/Modules/DoorState.cs index f4c0b92..516fb15 100644 --- a/Assets/Engine/Runtime/Modules/DoorState.cs +++ b/Assets/Engine/Runtime/Modules/DoorState.cs @@ -10,10 +10,19 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules public delegate void DoorEventHandler(DoorModule source, DoorEventType e); + /// + /// The of a . Handles all events that can occur for a door. + /// public class DoorState : ModuleState { + /// + /// Add event handlers to this hook to receive all events concerning this door. + /// public event DoorEventHandler DoorEvent; + /// + /// The door module this state belongs to. + /// protected DoorModule Module { get; set; } public bool Unlocked { diff --git a/Assets/Engine/Runtime/Modules/Module.cs b/Assets/Engine/Runtime/Modules/Module.cs index 23b96b3..c3503fb 100644 --- a/Assets/Engine/Runtime/Modules/Module.cs +++ b/Assets/Engine/Runtime/Modules/Module.cs @@ -10,6 +10,9 @@ using Object = UnityEngine.Object; namespace EscapeRoomEngine.Engine.Runtime.Modules { + /// + /// The main representation of a module. Contains references to the module description, state and handles its placement. + /// public class Module { public readonly List relatedModules = new(); diff --git a/Assets/Engine/Runtime/Modules/ModuleDescription.cs b/Assets/Engine/Runtime/Modules/ModuleDescription.cs index c42a2ca..47be1b1 100644 --- a/Assets/Engine/Runtime/Modules/ModuleDescription.cs +++ b/Assets/Engine/Runtime/Modules/ModuleDescription.cs @@ -5,9 +5,13 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Modules { + /// + /// The description of a specific module variant. Includes any requirements, the types and the module state that should be initialised with the module. + /// [CreateAssetMenu(menuName = "Modules/Generic Module")] public class ModuleDescription : ScriptableObject { + [Tooltip("The module types decide how this module can be used.")] public List types = new(); public ModuleState modulePrefab; [BoxGroup("Requirements")] diff --git a/Assets/Engine/Runtime/Modules/ModuleState.cs b/Assets/Engine/Runtime/Modules/ModuleState.cs index 5578269..a8532a3 100644 --- a/Assets/Engine/Runtime/Modules/ModuleState.cs +++ b/Assets/Engine/Runtime/Modules/ModuleState.cs @@ -2,8 +2,12 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules { + /// + /// An abstract module state. Example implementations are and . + /// public abstract class ModuleState : MonoBehaviour { + [Tooltip("The size of this module in meters.")] public Vector2Int size = Vector2Int.one; public abstract void SetModule(Module module); diff --git a/Assets/Engine/Runtime/Modules/ModuleType.cs b/Assets/Engine/Runtime/Modules/ModuleType.cs index 40728b4..a6469e9 100644 --- a/Assets/Engine/Runtime/Modules/ModuleType.cs +++ b/Assets/Engine/Runtime/Modules/ModuleType.cs @@ -1,5 +1,8 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules { + /// + /// A module can have one or multiple types. + /// public enum ModuleType { DoorEntrance, DoorExit, // door types diff --git a/Assets/Engine/Runtime/Modules/PuzzleModule.cs b/Assets/Engine/Runtime/Modules/PuzzleModule.cs index d3ef707..efd2f53 100644 --- a/Assets/Engine/Runtime/Modules/PuzzleModule.cs +++ b/Assets/Engine/Runtime/Modules/PuzzleModule.cs @@ -3,8 +3,14 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Modules { + /// + /// The main component of any puzzle module. + /// public class PuzzleModule : Module { + /// + /// The module state of this puzzle as a . + /// internal PuzzleState PuzzleState => PuzzleState.FromState(State); internal PuzzleModule(Space space, PuzzleModuleDescription description) : base(space, description) {} @@ -13,6 +19,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules { base.InstantiateModule(parent); + // the room needs to know about this puzzle space.room.AddPuzzle(this); } diff --git a/Assets/Engine/Runtime/Modules/PuzzleModuleDescription.cs b/Assets/Engine/Runtime/Modules/PuzzleModuleDescription.cs index 68d3408..e0bd22a 100644 --- a/Assets/Engine/Runtime/Modules/PuzzleModuleDescription.cs +++ b/Assets/Engine/Runtime/Modules/PuzzleModuleDescription.cs @@ -3,13 +3,21 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Modules { + /// + /// The for a . Includes the description of the connected door. + /// [CreateAssetMenu(menuName = "Modules/Puzzle")] public class PuzzleModuleDescription : ModuleDescription { + [Tooltip("Each puzzle has a name that will be used to display it to the game master.")] + [InfoBox("Changes to the name or version of the puzzle change its ID, which means it will not be connected with any of its previous measures any more.", EInfoBoxType.Warning)] public string puzzleName; [InfoBox("Puzzle measurements will only be combined for the same puzzle with the same version. If large changes are made to the puzzle that might influence its measurements, the version should be incremented.")] public int puzzleVersion = 1; + /// + /// The ID of the puzzle is used in the database. + /// public int Id => puzzleName.GetHashCode() + puzzleVersion; public override string ToString() diff --git a/Assets/Engine/Runtime/Modules/PuzzleState.cs b/Assets/Engine/Runtime/Modules/PuzzleState.cs index b6aa7b4..6f0e1c3 100644 --- a/Assets/Engine/Runtime/Modules/PuzzleState.cs +++ b/Assets/Engine/Runtime/Modules/PuzzleState.cs @@ -1,5 +1,6 @@ using System; using EscapeRoomEngine.Engine.Runtime.Utilities; +using JetBrains.Annotations; using NaughtyAttributes; using UnityEngine; using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger; @@ -28,11 +29,20 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules public delegate void PuzzleEventHandler(PuzzleModule source, PuzzleEventType e); + /// + /// The of a . Handles all events that can occur for a door. + /// [SelectionBase] public class PuzzleState : ModuleState { + /// + /// Add event handlers to this hook to receive all events concerning this puzzle. + /// public event PuzzleEventHandler PuzzleEvent; + /// + /// The puzzle module this state belongs to. + /// protected PuzzleModule Module { get; private set; } public bool Solved { @@ -69,8 +79,11 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules #region Debug Buttons - [Button(enabledMode: EButtonEnableMode.Playmode)] public void Solve() => Solved = true; - [Button(enabledMode: EButtonEnableMode.Playmode)] public void Restart() => Solved = false; + [Button(enabledMode: EButtonEnableMode.Playmode)] + public void Solve() => Solved = true; + [UsedImplicitly] + [Button(enabledMode: EButtonEnableMode.Playmode)] + public void Restart() => Solved = false; [Button("Trigger Wrong Input", EButtonEnableMode.Playmode)] public void WrongInput() { diff --git a/Assets/Engine/Runtime/Modules/Spawn.cs b/Assets/Engine/Runtime/Modules/Spawn.cs index 5b4f3f3..5cb0e90 100644 --- a/Assets/Engine/Runtime/Modules/Spawn.cs +++ b/Assets/Engine/Runtime/Modules/Spawn.cs @@ -1,5 +1,8 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules { + /// + /// The spawn door is used in the first room. + /// internal class Spawn : DoorState { private void Start() diff --git a/Assets/Engine/Runtime/Modules/StatePuzzle.cs b/Assets/Engine/Runtime/Modules/StatePuzzle.cs index 183d3ea..491fada 100644 --- a/Assets/Engine/Runtime/Modules/StatePuzzle.cs +++ b/Assets/Engine/Runtime/Modules/StatePuzzle.cs @@ -6,11 +6,20 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Modules { + /// + /// The of a puzzle that requires a specific state to be solved. + /// public class StatePuzzle : PuzzleState { + [Tooltip("The state this puzzle starts at.")] [BoxGroup("State Puzzle")] [SerializeField] - protected List states, solution; + protected List states; + [Tooltip("The state that needs to be reached for this puzzle to be solved.")] + [BoxGroup("State Puzzle")] + [SerializeField] + protected List solution; + [Tooltip("Set this to the total number of states this puzzle has.")] [BoxGroup("State Puzzle")] [SerializeField] [ValidateInput("CorrectStateCount", "States count must be equal to the number of states and the length of the solution.")] @@ -76,7 +85,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules } } - [UsedImplicitly] + [UsedImplicitly] // used for field validation private bool CorrectStateCount(int count) => states != null && count == states.Count && solution != null && count == solution.Count; diff --git a/Assets/Engine/Runtime/Modules/StepPuzzle.cs b/Assets/Engine/Runtime/Modules/StepPuzzle.cs index 01fcb54..5b692df 100644 --- a/Assets/Engine/Runtime/Modules/StepPuzzle.cs +++ b/Assets/Engine/Runtime/Modules/StepPuzzle.cs @@ -6,12 +6,16 @@ using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace EscapeRoomEngine.Engine.Runtime.Modules { + /// + /// The of a puzzle that includes a number of steps that need to be completed to solve it. + /// public abstract class StepPuzzle : PuzzleState { [BoxGroup("Step Puzzle")] [InfoBox("In easy mode, the step puzzle will not reset if a wrong input is made.")] public bool easyMode; - [BoxGroup("Step Puzzle")] [Min(0)] public int totalSteps; + [BoxGroup("Step Puzzle")] [Min(0)] + public int totalSteps; [BoxGroup("Step Puzzle")] [ProgressBar("Step", "totalSteps", EColor.Orange)] public int currentStep; diff --git a/Assets/Engine/Runtime/Orientation.cs b/Assets/Engine/Runtime/Orientation.cs index 0370fc4..5d2bc06 100644 --- a/Assets/Engine/Runtime/Orientation.cs +++ b/Assets/Engine/Runtime/Orientation.cs @@ -14,12 +14,24 @@ namespace EscapeRoomEngine.Engine.Runtime Orientation.North, Orientation.East, Orientation.South, Orientation.West }); + /// + /// Return the orientation corresponding to an angle, starting at 0 degrees North and going clockwise around the compass. + /// public static Orientation FromAngle(int angle) => (Orientation)angle; + /// + /// Turn an orientation into its corresponding angle. + /// public static float Angle(this Orientation orientation) => (float)orientation; + /// + /// Turn an orientation into its corresponding angle. + /// public static int AngleInt(this Orientation orientation) => (int)orientation; + /// + /// Rotate an orientation by a specific amount of quarter rotations. Rotating East thrice would return North. + /// public static Orientation Rotated(this Orientation orientation, int quarterRotations) => orientation + quarterRotations * 90; } diff --git a/Assets/Engine/Runtime/Passage.cs b/Assets/Engine/Runtime/Passage.cs index fe47fce..49281e7 100644 --- a/Assets/Engine/Runtime/Passage.cs +++ b/Assets/Engine/Runtime/Passage.cs @@ -5,9 +5,18 @@ using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace EscapeRoomEngine.Engine.Runtime { + /// + /// The passage handles the two door modules that connect two spaces. + /// public class Passage { + /// + /// The exit door in the previous room. + /// internal readonly DoorModule fromOut; + /// + /// The entrance door in the next room. + /// internal DoorModule toIn; internal Passage(DoorModule from) @@ -20,6 +29,9 @@ namespace EscapeRoomEngine.Engine.Runtime fromOut = from; } + /// + /// Place an entrance door in the same position relative to the room origin as the exit door. + /// internal void PlaceEntrance(DoorModule door) { if (!door.IsEntrance) @@ -35,6 +47,9 @@ namespace EscapeRoomEngine.Engine.Runtime Logger.Log($"Placed entrance {toIn} at {toIn.RrPosition} (RR)", LogType.ModulePlacement); } + /// + /// Connect the two doors in this passage. + /// internal void ConnectDoors() { toIn.Passage = this; @@ -43,6 +58,9 @@ namespace EscapeRoomEngine.Engine.Runtime Logger.Log($"Connected passage from {fromOut} to {toIn}", LogType.PassageConnection); } + /// + /// Return the door connected to a given door in this passage. + /// internal DoorModule Other(DoorModule of) { if (of.Equals(fromOut)) diff --git a/Assets/Engine/Runtime/Placement.cs b/Assets/Engine/Runtime/Placement.cs index 6999ae0..7cf1295 100644 --- a/Assets/Engine/Runtime/Placement.cs +++ b/Assets/Engine/Runtime/Placement.cs @@ -5,6 +5,9 @@ using Range = EscapeRoomEngine.Engine.Runtime.Utilities.Range; namespace EscapeRoomEngine.Engine.Runtime { + /// + /// A placement defines the position, size and orientation of a module or space. + /// public struct Placement { /// @@ -16,6 +19,9 @@ namespace EscapeRoomEngine.Engine.Runtime public Vector2Int size; public Orientation orientation; + /// + /// Return the bottom left corner position of the module. + /// public Vector3Int BottomLeft { get { diff --git a/Assets/Engine/Runtime/Requirements/FaceSpaceCenter.cs b/Assets/Engine/Runtime/Requirements/FaceSpaceCenter.cs index 99ebc11..f0e14e8 100644 --- a/Assets/Engine/Runtime/Requirements/FaceSpaceCenter.cs +++ b/Assets/Engine/Runtime/Requirements/FaceSpaceCenter.cs @@ -4,6 +4,9 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Requirements { + /// + /// This requirement guarantees that the module faces the center of the space. + /// [CreateAssetMenu(menuName = "Requirements/Face Space Center")] public class FaceSpaceCenter : PlacementRequirement { diff --git a/Assets/Engine/Runtime/Requirements/LockOrientation.cs b/Assets/Engine/Runtime/Requirements/LockOrientation.cs index dc127aa..0988d01 100644 --- a/Assets/Engine/Runtime/Requirements/LockOrientation.cs +++ b/Assets/Engine/Runtime/Requirements/LockOrientation.cs @@ -4,6 +4,9 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Requirements { + /// + /// This requirement forces a specific orientation. + /// [CreateAssetMenu(menuName = "Requirements/Lock Orientation")] public class LockOrientation : PlacementRequirement { diff --git a/Assets/Engine/Runtime/Requirements/NoOverlap.cs b/Assets/Engine/Runtime/Requirements/NoOverlap.cs index 5aa4f15..e461007 100644 --- a/Assets/Engine/Runtime/Requirements/NoOverlap.cs +++ b/Assets/Engine/Runtime/Requirements/NoOverlap.cs @@ -4,6 +4,9 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Requirements { + /// + /// This requirement prevents modules from overlapping. For two models not to overlap, both of them need this requirement. + /// [CreateAssetMenu(menuName = "Requirements/No Overlap")] public class NoOverlap : PlacementRequirement { diff --git a/Assets/Engine/Runtime/Requirements/PlaceAlongSpaceEdges.cs b/Assets/Engine/Runtime/Requirements/PlaceAlongSpaceEdges.cs index 82bf129..f45047a 100644 --- a/Assets/Engine/Runtime/Requirements/PlaceAlongSpaceEdges.cs +++ b/Assets/Engine/Runtime/Requirements/PlaceAlongSpaceEdges.cs @@ -4,6 +4,9 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Requirements { + /// + /// This requirement guarantees that the back side of the module is placed at the edge of the space. + /// [CreateAssetMenu(menuName = "Requirements/Place Along Space Edges")] public class PlaceAlongSpaceEdges : PlacementRequirement { diff --git a/Assets/Engine/Runtime/Requirements/PlaceAnywhere.cs b/Assets/Engine/Runtime/Requirements/PlaceAnywhere.cs index 33fcb92..ec330e4 100644 --- a/Assets/Engine/Runtime/Requirements/PlaceAnywhere.cs +++ b/Assets/Engine/Runtime/Requirements/PlaceAnywhere.cs @@ -4,6 +4,9 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Requirements { + /// + /// This requirement allows any placement. Used for testing purposes. + /// [CreateAssetMenu(menuName = "Requirements/Place Anywhere")] public class PlaceAnywhere : PlacementRequirement { diff --git a/Assets/Engine/Runtime/Requirements/PlaceWithRelatedModule.cs b/Assets/Engine/Runtime/Requirements/PlaceWithRelatedModule.cs index 50d2724..d36aea0 100644 --- a/Assets/Engine/Runtime/Requirements/PlaceWithRelatedModule.cs +++ b/Assets/Engine/Runtime/Requirements/PlaceWithRelatedModule.cs @@ -4,6 +4,9 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Requirements { + /// + /// This requirement places a module exactly in the same position as its first related module. + /// [CreateAssetMenu(menuName = "Requirements/Place With Related Module")] public class PlaceWithRelatedModule : PlacementRequirement { diff --git a/Assets/Engine/Runtime/Requirements/PlacementRequirement.cs b/Assets/Engine/Runtime/Requirements/PlacementRequirement.cs index dac2f19..ddf86ee 100644 --- a/Assets/Engine/Runtime/Requirements/PlacementRequirement.cs +++ b/Assets/Engine/Runtime/Requirements/PlacementRequirement.cs @@ -5,6 +5,9 @@ using EscapeRoomEngine.Engine.Runtime.Utilities; namespace EscapeRoomEngine.Engine.Runtime.Requirements { + /// + /// The main class any placement requirement inherits from. To place a module, every possible placement inside the space is put into a list of candidates that is then filtered by all placement requirements. + /// public abstract class PlacementRequirement : Requirement { protected abstract override List FilterCandidates(List candidates, Module module, Space space); diff --git a/Assets/Engine/Runtime/Requirements/PreconditionRequirement.cs b/Assets/Engine/Runtime/Requirements/PreconditionRequirement.cs index 41492a8..c8e93c2 100644 --- a/Assets/Engine/Runtime/Requirements/PreconditionRequirement.cs +++ b/Assets/Engine/Runtime/Requirements/PreconditionRequirement.cs @@ -5,6 +5,9 @@ using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace EscapeRoomEngine.Engine.Runtime.Requirements { + /// + /// The main class any precondition requirement inherits from. To place a module, each precondition requirement must return the true-set. + /// public abstract class PreconditionRequirement : Requirement { private static readonly List TrueSet = new(new[] { true }); diff --git a/Assets/Engine/Runtime/Requirements/RelatedModule.cs b/Assets/Engine/Runtime/Requirements/RelatedModule.cs index 56655e7..a1fc701 100644 --- a/Assets/Engine/Runtime/Requirements/RelatedModule.cs +++ b/Assets/Engine/Runtime/Requirements/RelatedModule.cs @@ -5,6 +5,9 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Requirements { + /// + /// This requirement guarantees that a module is placed in the same space as its related module. + /// [CreateAssetMenu(menuName = "Requirements/Related Module")] class RelatedModule : PreconditionRequirement { diff --git a/Assets/Engine/Runtime/Requirements/Requirement.cs b/Assets/Engine/Runtime/Requirements/Requirement.cs index 9b29623..e66eeeb 100644 --- a/Assets/Engine/Runtime/Requirements/Requirement.cs +++ b/Assets/Engine/Runtime/Requirements/Requirement.cs @@ -5,6 +5,9 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Requirements { + /// + /// A generic requirement class that defines how requirements filter candidates. + /// public abstract class Requirement : ScriptableObject { protected abstract List FilterCandidates(List candidates, Module module, Space space); diff --git a/Assets/Engine/Runtime/Room.cs b/Assets/Engine/Runtime/Room.cs index 52918ce..2b08d14 100644 --- a/Assets/Engine/Runtime/Room.cs +++ b/Assets/Engine/Runtime/Room.cs @@ -8,12 +8,18 @@ using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace EscapeRoomEngine.Engine.Runtime { + /// + /// A room manages an entrance to its first space and exit from its last space. It is also responsible for instantiating all spaces in it. + /// public class Room { internal Passage entrance, exit; internal GameObject roomObject; internal readonly List puzzles = new(); + /// + /// Return whether this room is the last room of the experience, determined by whether this room has an exit. + /// internal bool LastRoom => exit == null; private readonly List _spaces = new(); diff --git a/Assets/Engine/Runtime/Space.cs b/Assets/Engine/Runtime/Space.cs index 76698d5..5b3c624 100644 --- a/Assets/Engine/Runtime/Space.cs +++ b/Assets/Engine/Runtime/Space.cs @@ -10,12 +10,18 @@ using Range = EscapeRoomEngine.Engine.Runtime.Utilities.Range; namespace EscapeRoomEngine.Engine.Runtime { + /// + /// The space is responsible for placing and instantiating any modules in it. + /// public class Space { /// /// The room relative (RR) dimensions of this space. /// internal readonly Placement rrPlacement; + /// + /// The room this space is in. + /// internal readonly Room room; /// diff --git a/Assets/Engine/Runtime/SpaceTile.cs b/Assets/Engine/Runtime/SpaceTile.cs index 9b79ed3..ecdc54b 100644 --- a/Assets/Engine/Runtime/SpaceTile.cs +++ b/Assets/Engine/Runtime/SpaceTile.cs @@ -21,6 +21,9 @@ namespace EscapeRoomEngine.Engine.Runtime public GameObject prefab; } + /// + /// A space tile contains all game objects necessary to create a space from 2m x 2m up to any size. + /// public class SpaceTile : MonoBehaviour { public static HashSet EveryTileLocation => new(new[] diff --git a/Assets/Engine/Runtime/UI/GameControl.cs b/Assets/Engine/Runtime/UI/GameControl.cs index 8c3fed9..724f05c 100644 --- a/Assets/Engine/Runtime/UI/GameControl.cs +++ b/Assets/Engine/Runtime/UI/GameControl.cs @@ -13,12 +13,22 @@ namespace EscapeRoomEngine.Engine.Runtime.UI Stopped, Paused, Running } + /// + /// The component that manages the gamemaster UI and the time. + /// public class GameControl : MonoBehaviour { + /// + /// The active instance of the game control. + /// public static GameControl Instance { get; private set; } + [Tooltip("How much time in seconds should be between UI updates.")] [SerializeField] - private float uiUpdateInterval = 1, planUpdateInterval = 1; + private float uiUpdateInterval = 1; + [Tooltip("How much time in seconds should be between puzzle plan updates.")] + [SerializeField] + private float planUpdateInterval = 1; [BoxGroup("Internal")] [SerializeField] private Button startButton, stopButton, pauseButton, addTimeButton, removeTimeButton; [BoxGroup("Internal")] [SerializeField] @@ -36,10 +46,25 @@ namespace EscapeRoomEngine.Engine.Runtime.UI set => puzzlePlan.Puzzles = value; } + /// + /// The time that elapsed since the game was started. + /// public float TimeElapsed { get; private set; } + /// + /// The time the player has spent in this room. + /// public float TimeInRoom { get; set; } + /// + /// The target time set by the game master. + /// public float TargetTime { get; private set; } + /// + /// The estimated total time the player will have spent when they finish this room. + /// public float EstimatedTimeRoom { get; private set; } + /// + /// The estimated total time the player will spend in the experience. + /// public float EstimatedTime { get; private set; } private float _previousUIUpdate, _previousPlanUpdate; diff --git a/Assets/Engine/Runtime/UI/PauseButton.cs b/Assets/Engine/Runtime/UI/PauseButton.cs index cae762c..040424b 100644 --- a/Assets/Engine/Runtime/UI/PauseButton.cs +++ b/Assets/Engine/Runtime/UI/PauseButton.cs @@ -4,6 +4,9 @@ using UnityEngine.UI; namespace EscapeRoomEngine.Engine.Runtime.UI { + /// + /// This component is responsible to change the icon of the pause button depending on the game state. + /// public class PauseButton : MonoBehaviour { [BoxGroup("Internal")] [SerializeField] diff --git a/Assets/Engine/Runtime/UI/PuzzlePlan.cs b/Assets/Engine/Runtime/UI/PuzzlePlan.cs index fe08b73..02787e8 100644 --- a/Assets/Engine/Runtime/UI/PuzzlePlan.cs +++ b/Assets/Engine/Runtime/UI/PuzzlePlan.cs @@ -2,12 +2,17 @@ using System.Collections.Generic; using EscapeRoomEngine.Engine.Runtime.Modules; using NaughtyAttributes; using UnityEngine; -using UnityEngine.UI; namespace EscapeRoomEngine.Engine.Runtime.UI { + /// + /// The puzzle plan UI component that displays the current puzzle plan in the game master window. + /// public class PuzzlePlan : MonoBehaviour { + /// + /// The distance from one entry to the next. + /// [SerializeField] private Vector2 entryOffset; [BoxGroup("Internal")] [SerializeField] diff --git a/Assets/Engine/Runtime/UI/PuzzlePlanEntry.cs b/Assets/Engine/Runtime/UI/PuzzlePlanEntry.cs index 5b20314..d84535b 100644 --- a/Assets/Engine/Runtime/UI/PuzzlePlanEntry.cs +++ b/Assets/Engine/Runtime/UI/PuzzlePlanEntry.cs @@ -1,4 +1,3 @@ -using System; using EscapeRoomEngine.Engine.Runtime.Measurements; using EscapeRoomEngine.Engine.Runtime.Modules; using EscapeRoomEngine.Engine.Runtime.Utilities; @@ -8,6 +7,9 @@ using UnityEngine.UI; namespace EscapeRoomEngine.Engine.Runtime.UI { + /// + /// An entry in the UI component that displays the name and estimated time for a puzzle. + /// public class PuzzlePlanEntry : MonoBehaviour { [BoxGroup("Internal")] [Required] [SerializeField] diff --git a/Assets/Engine/Runtime/Utilities/Backtrack.cs b/Assets/Engine/Runtime/Utilities/Backtrack.cs index d2d4c47..daaa240 100644 --- a/Assets/Engine/Runtime/Utilities/Backtrack.cs +++ b/Assets/Engine/Runtime/Utilities/Backtrack.cs @@ -2,9 +2,11 @@ using System; // ReSharper disable ReturnTypeCanBeEnumerable.Global // ReSharper disable ParameterTypeCanBeEnumerable.Local - namespace EscapeRoomEngine.Engine.Runtime.Utilities { + /// + /// The backtrack algorithm can calculate the subset of a set of samples with the sum closest to a target value. + /// public struct Backtrack { private int[] indices; @@ -95,6 +97,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Utilities return Sum(leave) < Sum(pick) ? leave : pick; } + /// + /// Combine the two brute force algorithms to calculate the optimal subset. + /// public int[] BruteForce() { var lower = BruteForceLower(); diff --git a/Assets/Engine/Runtime/Utilities/DisablePicking.cs b/Assets/Engine/Runtime/Utilities/DisablePicking.cs index b54a145..11451dc 100644 --- a/Assets/Engine/Runtime/Utilities/DisablePicking.cs +++ b/Assets/Engine/Runtime/Utilities/DisablePicking.cs @@ -1,8 +1,11 @@ using UnityEditor; using UnityEngine; -namespace EscapeRoomEngine.Desert.Runtime +namespace EscapeRoomEngine.Engine.Runtime.Utilities { + /// + /// This component disables a certain game object from being selectable in the scene view. + /// public class DisablePicking : MonoBehaviour { public GameObject objectToDisable; diff --git a/Assets/Engine/Runtime/Utilities/DynamicColor.cs b/Assets/Engine/Runtime/Utilities/DynamicColor.cs index 562f012..cb8a9d6 100644 --- a/Assets/Engine/Runtime/Utilities/DynamicColor.cs +++ b/Assets/Engine/Runtime/Utilities/DynamicColor.cs @@ -3,6 +3,9 @@ using UnityEngine; namespace EscapeRoomEngine.Engine.Runtime.Utilities { + /// + /// Stores both the hdr and ldr version of a colour. + /// [Serializable] public struct DynamicColor { diff --git a/Assets/Engine/Runtime/Utilities/Logger.cs b/Assets/Engine/Runtime/Utilities/Logger.cs index 2089bec..d0d527a 100644 --- a/Assets/Engine/Runtime/Utilities/Logger.cs +++ b/Assets/Engine/Runtime/Utilities/Logger.cs @@ -19,25 +19,24 @@ namespace EscapeRoomEngine.Engine.Runtime.Utilities public class Logger : MonoBehaviour { - public static Logger DefaultLogger - { - get - { - if (_foundLogger == null) - { - _foundLogger = FindObjectOfType(); - } - return _foundLogger; - } - } - private static Logger _foundLogger; + /// + /// The active instance of the logger. + /// + private static Logger Instance { get; set; } + [Tooltip("Toggle logging on or off globally.")] public bool loggingEnabled; + [Tooltip("This list determines what types of log messages should be displayed.")] public List typeFilter; + + private void Awake() + { + Instance = this; + } public static void Log(string message, LogType type) { - if (DefaultLogger.loggingEnabled && DefaultLogger.typeFilter.Contains(type)) + if (Instance.loggingEnabled && Instance.typeFilter.Contains(type)) { Debug.Log($"[{type}] {message}"); } diff --git a/Assets/Engine/Runtime/Utilities/Probability.cs b/Assets/Engine/Runtime/Utilities/Probability.cs index 043b593..cd09488 100644 --- a/Assets/Engine/Runtime/Utilities/Probability.cs +++ b/Assets/Engine/Runtime/Utilities/Probability.cs @@ -6,12 +6,25 @@ using Random = System.Random; namespace EscapeRoomEngine.Engine.Runtime.Utilities { + /// + /// The representation of a normal distribution with a certain mean μ and standard deviation σ. + /// [Serializable] public struct NormalDistribution { - public float μ, σ; + /// + /// The mean of this distribution. + /// + public float μ; + /// + /// The standard deviation of this distribution. + /// + public float σ; - public static NormalDistribution Standard => new NormalDistribution { μ = 0, σ = 1 }; + /// + /// Generate a standard normal distribution. + /// + public static NormalDistribution Standard => new() { μ = 0, σ = 1 }; public NormalDistribution(float[] samples) : this() { @@ -19,13 +32,25 @@ namespace EscapeRoomEngine.Engine.Runtime.Utilities σ = Probability.StandardDeviation(samples, μ); } + /// + /// Sample a random value from this distribution. + /// public float Sample() => σ * Probability.Normal() + μ; + /// + /// Sample the CDF of this distribution. + /// public float Cumulative(float x) => (float)new Normal(μ, σ).CumulativeDistribution(x); + /// + /// Sample the inverse CDF of this distribution. + /// public float InverseCumulative(float x) => (float)new Normal(μ, σ).InverseCumulativeDistribution(x); } + /// + /// This class is used for probability calculations. + /// public static class Probability { private static readonly Random _random = new(); @@ -50,6 +75,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Utilities return u1 * Mathf.Sqrt(-2 * Mathf.Log(square) / square); } + /// + /// Calculate the mean of a list of samples. + /// public static float Mean(float[] samples) { if (samples.Length == 0) @@ -60,7 +88,13 @@ namespace EscapeRoomEngine.Engine.Runtime.Utilities return samples.Sum() / samples.Length; } + /// + /// Calculate the standard deviation of a list of samples. + /// public static float StandardDeviation(float[] samples) => StandardDeviation(samples, Mean(samples)); + /// + /// Calculate the standard deviation of a list of samples without recalculating the mean. + /// public static float StandardDeviation(float[] samples, float mean) { var deviations = new float[samples.Length]; diff --git a/Assets/Engine/Runtime/Utilities/Range.cs b/Assets/Engine/Runtime/Utilities/Range.cs index d36a74f..48448e1 100644 --- a/Assets/Engine/Runtime/Utilities/Range.cs +++ b/Assets/Engine/Runtime/Utilities/Range.cs @@ -1,9 +1,15 @@ namespace EscapeRoomEngine.Engine.Runtime.Utilities { + /// + /// This struct represents an integer range. + /// public struct Range { public int min, max; + /// + /// The length of the range, excluding the maximum value. + /// public int Length => max - min; public Range(int min, int max) @@ -12,6 +18,9 @@ this.max = max; } + /// + /// Create an array of every value in this range. + /// public int[] ToArray(bool includeMax = false) { var count = includeMax ? Length + 1 : Length; diff --git a/Assets/Engine/Runtime/Utilities/Utilities.cs b/Assets/Engine/Runtime/Utilities/Utilities.cs index 11a5943..5b718f9 100644 --- a/Assets/Engine/Runtime/Utilities/Utilities.cs +++ b/Assets/Engine/Runtime/Utilities/Utilities.cs @@ -23,6 +23,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Utilities #region Randomness + /// + /// Return a random value in a range, including the last value. + /// public static int RandomInclusive(int from, int to) => Random.Range(from, to + 1); #endregion @@ -41,6 +44,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Utilities return element; } + /// + /// Return a random value from a list. + /// public static T RandomElement(this List list) => list[Random.Range(0, list.Count)]; /// @@ -59,8 +65,14 @@ namespace EscapeRoomEngine.Engine.Runtime.Utilities public static class Vector2IntExtensions { + /// + /// Project a 2D vector onto the floor in 3D space. + /// public static Vector3Int ProjectAtFloor(this Vector2Int vector) => vector.ProjectAtHeight(0); + /// + /// Project a 2D vector onto a specific height in 3D space. + /// public static Vector3Int ProjectAtHeight(this Vector2Int vector, int height) => new Vector3Int(vector.x, height, vector.y); } diff --git a/Assets/Portal/Runtime/Portal.cs b/Assets/Portal/Runtime/Portal.cs index 250d1be..907a45b 100644 --- a/Assets/Portal/Runtime/Portal.cs +++ b/Assets/Portal/Runtime/Portal.cs @@ -7,6 +7,9 @@ using UnityEngine; namespace EscapeRoomEngine.Portal.Runtime { + /// + /// The portal is a specific type of for seamless transitions between spaces. + /// public class Portal : DoorState { public static readonly Matrix4x4 HalfRotation = Matrix4x4.Rotate(Quaternion.Euler(0, 180, 0)); @@ -24,6 +27,9 @@ namespace EscapeRoomEngine.Portal.Runtime /// [BoxGroup("Internal")] public Transform portalTransform; + /// + /// Whether this portal is connected is determined by whether the reference to its linked portal is set. + /// internal bool Connected => linkedPortal != null; internal readonly List closePortalDrivers = new(); @@ -70,6 +76,9 @@ namespace EscapeRoomEngine.Portal.Runtime } } + /// + /// Begin tracking a portal driver that came close to this portal and might need to be teleported. + /// internal void StartTrackingDriver(PortalDriver portalDriver, int entrySide) { closePortalDrivers.Add(portalDriver); @@ -77,12 +86,18 @@ namespace EscapeRoomEngine.Portal.Runtime portalDriver.entrySide = entrySide; } + /// + /// End tracking a portal driver that distanced itself from this portal or was teleported to the linked portal. + /// internal void StopTrackingDriver(PortalDriver portalDriver) { closePortalDrivers.Remove(portalDriver); portalDriver.DisableClone(linkedPortal); } + /// + /// Calculate which side of the portal plane a transform is. + /// internal int CalculateSide(Transform portalDriverTransform) { return Math.Sign(Vector3.Dot(portalTransform.forward, portalDriverTransform.position - portalTransform.position)); diff --git a/Assets/Portal/Runtime/PortalCamera.cs b/Assets/Portal/Runtime/PortalCamera.cs index 79b8e3d..3304e01 100644 --- a/Assets/Portal/Runtime/PortalCamera.cs +++ b/Assets/Portal/Runtime/PortalCamera.cs @@ -38,7 +38,7 @@ namespace EscapeRoomEngine.Portal.Runtime private void Awake() { // get player camera - _player = Player.Current; + _player = Player.Instance; // get portal camera _camera = GetComponent(); diff --git a/Assets/Portal/Runtime/PortalCollider.cs b/Assets/Portal/Runtime/PortalCollider.cs index 2a4450c..d34deba 100644 --- a/Assets/Portal/Runtime/PortalCollider.cs +++ b/Assets/Portal/Runtime/PortalCollider.cs @@ -4,6 +4,9 @@ using UnityEngine; namespace EscapeRoomEngine.Portal.Runtime { + /// + /// The portal collider is responsible for detecting s that come close to this portal. + /// [RequireComponent(typeof(Collider))] public class PortalCollider : MonoBehaviour { diff --git a/Assets/Portal/Runtime/PortalDriver.cs b/Assets/Portal/Runtime/PortalDriver.cs index bc969b3..bfbbc88 100644 --- a/Assets/Portal/Runtime/PortalDriver.cs +++ b/Assets/Portal/Runtime/PortalDriver.cs @@ -4,6 +4,9 @@ using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace EscapeRoomEngine.Portal.Runtime { + /// + /// A portal driver is any object that can be teleported by a portal like the player, their hands or objects. + /// [RequireComponent(typeof(Collider), typeof(Rigidbody))] public class PortalDriver : MonoBehaviour { diff --git a/Assets/Portal/Runtime/PortalDriverClone.cs b/Assets/Portal/Runtime/PortalDriverClone.cs index 403ea9c..b3d73e3 100644 --- a/Assets/Portal/Runtime/PortalDriverClone.cs +++ b/Assets/Portal/Runtime/PortalDriverClone.cs @@ -4,6 +4,9 @@ using UnityEngine.XR.Interaction.Toolkit; namespace EscapeRoomEngine.Portal.Runtime { + /// + /// The clone of a is a copy of it that was stripped of most of its components. Its position is updated by the driver. + /// public class PortalDriverClone : MonoBehaviour { /// diff --git a/Assets/Test Assets/BacktrackingTest.cs b/Assets/Test Assets/BacktrackingTest.cs index fda089c..5c29a3b 100644 --- a/Assets/Test Assets/BacktrackingTest.cs +++ b/Assets/Test Assets/BacktrackingTest.cs @@ -5,6 +5,9 @@ using UnityEngine; namespace Test_Assets { + /// + /// This class is used to test the struct. + /// public class BacktrackingTest : MonoBehaviour { public int[] values; diff --git a/Assets/Test Assets/ProbabilityTest.cs b/Assets/Test Assets/ProbabilityTest.cs index 22747f7..db1d198 100644 --- a/Assets/Test Assets/ProbabilityTest.cs +++ b/Assets/Test Assets/ProbabilityTest.cs @@ -5,6 +5,9 @@ using UnityEngine; namespace Test_Assets { + /// + /// This class is used to test the < class. + /// public class ProbabilityTest : MonoBehaviour { public NormalDistribution distribution = NormalDistribution.Standard; diff --git a/Assets/VR/Runtime/Player.cs b/Assets/VR/Runtime/Player.cs index fe53350..8d84f99 100644 --- a/Assets/VR/Runtime/Player.cs +++ b/Assets/VR/Runtime/Player.cs @@ -3,21 +3,21 @@ using UnityEngine; namespace EscapeRoomEngine.VR.Runtime { + /// + /// The player component contains references to the main camera, eye positions and hand positions of the VR player. + /// public class Player : MonoBehaviour { - public static Player Current + /// + /// The active player instance. + /// + public static Player Instance { get; private set; } + + private void Awake() { - get - { - if (_foundPlayer == null) - { - _foundPlayer = FindObjectOfType(); - } - return _foundPlayer; - } + Instance = this; } - private static Player _foundPlayer; - + [BoxGroup("Internal")] public new Camera camera; [BoxGroup("Internal")] [SerializeField] private Transform leftEye, rightEye; [BoxGroup("Internal")] [SerializeField] private Collider leftHand, rightHand;