refactor modules
This commit is contained in:
124
Assets/Station46/Scripts/Button.cs
Normal file
124
Assets/Station46/Scripts/Button.cs
Normal file
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
|
||||
using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType;
|
||||
|
||||
namespace Station46.Runtime
|
||||
{
|
||||
public enum ButtonEventType
|
||||
{
|
||||
Pressed, Released, Activated, Deactivated
|
||||
}
|
||||
|
||||
public static class ButtonEventExtensions
|
||||
{
|
||||
public static string Description(this ButtonEventType type, Button button)
|
||||
{
|
||||
var action = type switch
|
||||
{
|
||||
ButtonEventType.Pressed => "pressed",
|
||||
ButtonEventType.Released => "released",
|
||||
ButtonEventType.Activated => "activated",
|
||||
ButtonEventType.Deactivated => "deactivated",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
|
||||
};
|
||||
|
||||
return $"{button} was {action}";
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void ButtonEventHandler(Button source, ButtonEventType e);
|
||||
|
||||
/// <summary>
|
||||
/// A general component for buttons that handles button events.
|
||||
/// </summary>
|
||||
public class Button : MonoBehaviour
|
||||
{
|
||||
public event ButtonEventHandler ButtonEvent;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this button accepts input.
|
||||
/// </summary>
|
||||
[ShowNativeProperty]
|
||||
protected bool Active
|
||||
{
|
||||
get => _active;
|
||||
set
|
||||
{
|
||||
var previous = _active;
|
||||
_active = value;
|
||||
|
||||
if (previous != _active)
|
||||
{
|
||||
OnButtonEvent(_active ? ButtonEventType.Activated : ButtonEventType.Deactivated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether this button is currently pressed.
|
||||
/// </summary>
|
||||
[ShowNativeProperty]
|
||||
protected bool Pressed
|
||||
{
|
||||
get => _pressed;
|
||||
set
|
||||
{
|
||||
var previous = _pressed;
|
||||
_pressed = Active && value;
|
||||
|
||||
if (previous != _pressed)
|
||||
{
|
||||
OnButtonEvent(_pressed ? ButtonEventType.Pressed : ButtonEventType.Released);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _active = true, _pressed;
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
ButtonEvent += (_, type) =>
|
||||
{
|
||||
if (type == ButtonEventType.Deactivated)
|
||||
{
|
||||
Pressed = false; // release button if it is deactivated
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void OnButtonEvent(ButtonEventType type)
|
||||
{
|
||||
Logger.Log(type.Description(this), LogType.PuzzleDetail);
|
||||
|
||||
ButtonEvent?.Invoke(this, type);
|
||||
}
|
||||
|
||||
#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;
|
||||
[UsedImplicitly]
|
||||
[Button(enabledMode: EButtonEnableMode.Playmode)]
|
||||
public void PressAndRelease()
|
||||
{
|
||||
Press();
|
||||
Release();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Station46/Scripts/Button.cs.meta
Normal file
3
Assets/Station46/Scripts/Button.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0388274fd30c44089477f6bed40e1e23
|
||||
timeCreated: 1668813709
|
||||
40
Assets/Station46/Scripts/CyclicStepPuzzle.cs
Normal file
40
Assets/Station46/Scripts/CyclicStepPuzzle.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Station46.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="StepPuzzle"/> whose steps are considered a cycle that can be started anywhere and must be stepped through once.
|
||||
/// </summary>
|
||||
public class CyclicStepPuzzle : StepPuzzle
|
||||
{
|
||||
[Tooltip("The current step in the cycle.")]
|
||||
[BoxGroup("Step Puzzle")] [Min(0)]
|
||||
public int cycleStep;
|
||||
|
||||
protected override void CheckStep(int step)
|
||||
{
|
||||
if (!Solved)
|
||||
{
|
||||
if (currentStep == 0)
|
||||
{
|
||||
// begin at any step
|
||||
cycleStep = NextInCycle(step);
|
||||
Step();
|
||||
}
|
||||
else if (step == cycleStep)
|
||||
{
|
||||
// next step in cycle
|
||||
cycleStep = NextInCycle(cycleStep);
|
||||
Step();
|
||||
}
|
||||
else
|
||||
{
|
||||
WrongInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int NextInCycle(int step) => (step + 1) % totalSteps;
|
||||
}
|
||||
}
|
||||
3
Assets/Station46/Scripts/CyclicStepPuzzle.cs.meta
Normal file
3
Assets/Station46/Scripts/CyclicStepPuzzle.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4551ae21288a497dac75931c56f86409
|
||||
timeCreated: 1669057382
|
||||
71
Assets/Station46/Scripts/Emission.cs
Normal file
71
Assets/Station46/Scripts/Emission.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Station46.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// A general component for controlling the emission of an object.
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the emission is on.
|
||||
/// </summary>
|
||||
internal bool active;
|
||||
|
||||
private bool _previousActive;
|
||||
private Color _previousColor;
|
||||
private Material _material;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_material = emissionRenderer.material;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
ChangedToggle();
|
||||
ChangedColor();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_previousActive != active)
|
||||
{
|
||||
ChangedToggle();
|
||||
_previousActive = active;
|
||||
}
|
||||
|
||||
if (!_previousColor.Equals(color))
|
||||
{
|
||||
ChangedColor();
|
||||
_previousColor = color;
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangedToggle()
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
_material.EnableKeyword("_EMISSION");
|
||||
}
|
||||
else
|
||||
{
|
||||
_material.DisableKeyword("_EMISSION");
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangedColor()
|
||||
{
|
||||
_material.SetColor(EmissionColorNameID, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Station46/Scripts/Emission.cs.meta
Normal file
3
Assets/Station46/Scripts/Emission.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17de1e2991b64847bceea06f966f0560
|
||||
timeCreated: 1668704065
|
||||
43
Assets/Station46/Scripts/HoloButton.cs
Normal file
43
Assets/Station46/Scripts/HoloButton.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Station46.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// A holographic <see cref="Button"/> that changes its colour when it is pressed.
|
||||
/// </summary>
|
||||
public class HoloButton : Button
|
||||
{
|
||||
private static readonly int FresnelColor = Shader.PropertyToID("_FresnelColor");
|
||||
private static readonly int Color = Shader.PropertyToID("_Color");
|
||||
|
||||
[BoxGroup("Internal")] [Required] public MeshRenderer holoRenderer;
|
||||
|
||||
private Material _material;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_material = holoRenderer.material;
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
ButtonEvent += (_, _) =>
|
||||
{
|
||||
var color = EscapeRoomEngine.Engine.Runtime.Engine.Theme.puzzleColor;
|
||||
if (!Active)
|
||||
{
|
||||
color = EscapeRoomEngine.Engine.Runtime.Engine.Theme.solvedColor;
|
||||
} else if (Pressed)
|
||||
{
|
||||
color = EscapeRoomEngine.Engine.Runtime.Engine.Theme.activeColor;
|
||||
}
|
||||
|
||||
_material.SetColor(FresnelColor, color.hdr);
|
||||
_material.SetColor(Color, color.hdr);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Station46/Scripts/HoloButton.cs.meta
Normal file
3
Assets/Station46/Scripts/HoloButton.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 352860bb2c6549d0b3e84104afef3f54
|
||||
timeCreated: 1670019940
|
||||
94
Assets/Station46/Scripts/StatePuzzle.cs
Normal file
94
Assets/Station46/Scripts/StatePuzzle.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using EscapeRoomEngine.Engine.Runtime.Modules.State;
|
||||
using JetBrains.Annotations;
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Station46.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="PuzzleState"/> of a puzzle that requires a specific state to be solved.
|
||||
/// </summary>
|
||||
public class StatePuzzle : PuzzleState
|
||||
{
|
||||
[Tooltip("The state this puzzle starts at.")]
|
||||
[BoxGroup("State Puzzle")]
|
||||
[SerializeField]
|
||||
protected List<int> states;
|
||||
[Tooltip("The state that needs to be reached for this puzzle to be solved.")]
|
||||
[BoxGroup("State Puzzle")]
|
||||
[SerializeField]
|
||||
protected List<int> 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.")]
|
||||
[Min(0)]
|
||||
protected int stateCount;
|
||||
[BoxGroup("State Puzzle")]
|
||||
[ProgressBar("Correct States", "stateCount", EColor.Orange)]
|
||||
public int correctStates;
|
||||
|
||||
private List<int> _initialStates;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_initialStates = new List<int>(states);
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
PuzzleEvent += (_, type) =>
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PuzzleEventType.Restarted:
|
||||
for (var i = 0; i < stateCount; i++)
|
||||
{
|
||||
SetState(i, _initialStates[i], false);
|
||||
}
|
||||
break;
|
||||
case PuzzleEventType.Solved:
|
||||
for (var i = 0; i < stateCount; i++)
|
||||
{
|
||||
SetState(i, solution[i], false);
|
||||
}
|
||||
break;
|
||||
case PuzzleEventType.WrongInput:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(type), type, null);
|
||||
}
|
||||
};
|
||||
|
||||
base.Start();
|
||||
}
|
||||
|
||||
protected virtual void SetState(int index, int value, bool checkSolution)
|
||||
{
|
||||
if (index >= 0 && index < stateCount)
|
||||
{
|
||||
states[index] = value;
|
||||
correctStates = 0;
|
||||
for (var i = 0; i < stateCount; i++)
|
||||
{
|
||||
if (states[i] == solution[i])
|
||||
{
|
||||
correctStates++;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkSolution && correctStates == stateCount && correctStates > 0)
|
||||
{
|
||||
Solve();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[UsedImplicitly] // used for field validation
|
||||
private bool CorrectStateCount(int count) =>
|
||||
states != null && count == states.Count &&
|
||||
solution != null && count == solution.Count;
|
||||
}
|
||||
}
|
||||
3
Assets/Station46/Scripts/StatePuzzle.cs.meta
Normal file
3
Assets/Station46/Scripts/StatePuzzle.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 713782041b1d40a28cfe199081a4a009
|
||||
timeCreated: 1669687388
|
||||
85
Assets/Station46/Scripts/StepPuzzle.cs
Normal file
85
Assets/Station46/Scripts/StepPuzzle.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using EscapeRoomEngine.Engine.Runtime.Modules.State;
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
|
||||
using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType;
|
||||
|
||||
namespace Station46.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="PuzzleState"/> of a puzzle that includes a number of steps that need to be completed to solve it.
|
||||
/// </summary>
|
||||
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")] [ProgressBar("Step", "totalSteps", EColor.Orange)]
|
||||
public int currentStep;
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
PuzzleEvent += (_, type) =>
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PuzzleEventType.Restarted:
|
||||
currentStep = 0;
|
||||
break;
|
||||
case PuzzleEventType.Solved:
|
||||
currentStep = totalSteps;
|
||||
break;
|
||||
case PuzzleEventType.WrongInput:
|
||||
if (!easyMode)
|
||||
{
|
||||
currentStep = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(type), type, null);
|
||||
}
|
||||
};
|
||||
|
||||
base.Start();
|
||||
}
|
||||
|
||||
protected virtual void CheckStep(int step)
|
||||
{
|
||||
if (!Solved)
|
||||
{
|
||||
if (step == currentStep)
|
||||
{
|
||||
Step();
|
||||
}
|
||||
else
|
||||
{
|
||||
WrongInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Debug Buttons
|
||||
|
||||
[Button(enabledMode: EButtonEnableMode.Playmode)]
|
||||
protected void Step()
|
||||
{
|
||||
if (!Solved)
|
||||
{
|
||||
currentStep++;
|
||||
if (currentStep >= totalSteps)
|
||||
{
|
||||
Solve();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Log($"{this} step {currentStep}/{totalSteps}", LogType.PuzzleDetail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
3
Assets/Station46/Scripts/StepPuzzle.cs.meta
Normal file
3
Assets/Station46/Scripts/StepPuzzle.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5095ea3f77724269857f7275fbf7159b
|
||||
timeCreated: 1669052447
|
||||
Reference in New Issue
Block a user