wip: Path to Omnissiah
This commit is contained in:
@@ -1,14 +1,38 @@
|
||||
using OctoCore;
|
||||
using OctoCore.Components;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
public class SpiralStaircase : MonoBehaviour
|
||||
{
|
||||
[System.Serializable]
|
||||
public class DoorsPair
|
||||
{
|
||||
public Transform Left;
|
||||
public Transform Right;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class State
|
||||
{
|
||||
public bool PlayerInside;
|
||||
public int Turns;
|
||||
public float TotalAngle;
|
||||
[Range(0, 1)] public float Progression;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class References
|
||||
{
|
||||
public UniversalRendererData RendererData;
|
||||
public GameObject Stairs;
|
||||
public DoorsPair[] Doors;
|
||||
public GameObject[] Inside;
|
||||
public GameObject[] Outside;
|
||||
}
|
||||
@@ -21,28 +45,43 @@ public class SpiralStaircase : MonoBehaviour
|
||||
public float EndAngle = 720;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class Events
|
||||
{
|
||||
public UnityEvent<bool> OnInside;
|
||||
public UnityEvent OnTopReached;
|
||||
public UnityEvent OnBottomReached;
|
||||
}
|
||||
|
||||
[SerializeField, OctoReadOnly] private State _state;
|
||||
[SerializeField] private References _references;
|
||||
[SerializeField] private Settings _settings;
|
||||
[SerializeField] private Events _events;
|
||||
|
||||
private bool _playerInside;
|
||||
[SerializeField] private int _turns;
|
||||
[SerializeField] private float _totalAngle;
|
||||
[SerializeField] private float _progression;
|
||||
private List<IEnumerator> _doorsCoroutine;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_doorsCoroutine = new List<IEnumerator>();
|
||||
for (int i = 0; i < _references.Doors.Length; i++)
|
||||
_doorsCoroutine.Add(null);
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
ManageInside();
|
||||
_events.OnBottomReached?.Invoke();
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
_playerInside = false;
|
||||
_state.PlayerInside = false;
|
||||
ManageInside();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (_playerInside)
|
||||
if (_state.PlayerInside)
|
||||
Count();
|
||||
}
|
||||
|
||||
@@ -50,9 +89,9 @@ public class SpiralStaircase : MonoBehaviour
|
||||
{
|
||||
if (OctoPlayer.Instance && OctoPlayer.Instance.gameObject == col.gameObject)
|
||||
{
|
||||
if (!_playerInside)
|
||||
if (!_state.PlayerInside)
|
||||
{
|
||||
_playerInside = true;
|
||||
_state.PlayerInside = true;
|
||||
ManageInside();
|
||||
}
|
||||
}
|
||||
@@ -62,49 +101,104 @@ public class SpiralStaircase : MonoBehaviour
|
||||
{
|
||||
if (OctoPlayer.Instance && OctoPlayer.Instance.gameObject == col.gameObject)
|
||||
{
|
||||
if (_playerInside)
|
||||
if (_state.PlayerInside)
|
||||
{
|
||||
_playerInside = false;
|
||||
_state.PlayerInside = false;
|
||||
ManageInside();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OpendDoors(bool open) { for (int i = 0; i < _references.Doors.Length; i++) OpendDoor(i, open); }
|
||||
public void OpendDoor(int id) { OpendDoor(id, true); }
|
||||
public void CloseDoor(int id) { OpendDoor(id, false); }
|
||||
public void SetDoorOpened(int id) { OpendDoor(id, true, false); }
|
||||
public void SetDoorClosed(int id) { OpendDoor(id, false, false); }
|
||||
|
||||
private void OpendDoor(int id, bool open, bool animate = true)
|
||||
{
|
||||
if (_doorsCoroutine[id] != null) StopCoroutine(_doorsCoroutine[id]);
|
||||
StartCoroutine(_doorsCoroutine[id] = OpenDoorCoroutine(id, open, animate));
|
||||
}
|
||||
|
||||
IEnumerator OpenDoorCoroutine(int id, bool open, bool animate)
|
||||
{
|
||||
const float duration = .6f;
|
||||
|
||||
DoorsPair door = _references.Doors[id];
|
||||
|
||||
Quaternion originRotL = door.Left.transform.localRotation;
|
||||
Quaternion originRotR = door.Right.transform.localRotation;
|
||||
Quaternion targetRotL = Quaternion.Euler(0, open ? 0 : 13.1f, 0);
|
||||
Quaternion targetRotR = Quaternion.Euler(0, open ? 0 :-13.1f, 0);
|
||||
|
||||
if (animate)
|
||||
{
|
||||
for (float t = 0; t < duration; t += Time.deltaTime)
|
||||
{
|
||||
float lerp = .5f - Mathf.Cos(t / duration * Mathf.PI) * .5f;
|
||||
|
||||
door.Left.transform.localRotation = Quaternion.Lerp(originRotL, targetRotL, lerp);
|
||||
door.Right.transform.localRotation = Quaternion.Lerp(originRotR, targetRotR, lerp);
|
||||
|
||||
yield return new WaitForEndOfFrame();
|
||||
}
|
||||
}
|
||||
|
||||
door.Left.transform.localRotation = targetRotL;
|
||||
door.Right.transform.localRotation = targetRotR;
|
||||
|
||||
_doorsCoroutine[id] = null;
|
||||
}
|
||||
|
||||
private void Count()
|
||||
{
|
||||
if (!OctoPlayer.Instance) return;
|
||||
|
||||
|
||||
Vector2[] steps = new Vector2[4] { Vector2.up, Vector2.left, Vector2.down, Vector2.right };
|
||||
Vector2 nextStep = steps[_turns % steps.Length];
|
||||
Vector2 nextStep = steps[_state.Turns % steps.Length];
|
||||
|
||||
Vector3 relativePos3D = transform.InverseTransformPoint(OctoPlayer.Instance.transform.position);
|
||||
Vector2 relativePos2D = new Vector2(relativePos3D.x, relativePos3D.z);
|
||||
|
||||
float quarterAngle = Vector2.Angle(nextStep, relativePos2D) * Mathf.Sign(Vector3.Cross(nextStep, relativePos2D).z);
|
||||
|
||||
_totalAngle = Mathf.Max(0, _turns * 90 + quarterAngle);
|
||||
_state.TotalAngle = Mathf.Max(0, _state.Turns * 90 + quarterAngle);
|
||||
|
||||
if (quarterAngle > 90 && quarterAngle < 100)
|
||||
{
|
||||
_turns++;
|
||||
_state.Turns++;
|
||||
}
|
||||
else if (quarterAngle < 0 && _turns > 0)
|
||||
else if (quarterAngle < 0 && _state.Turns > 0)
|
||||
{
|
||||
_turns--;
|
||||
_state.Turns--;
|
||||
}
|
||||
|
||||
_progression = Mathf.Clamp01(Mathf.InverseLerp(_settings.StartAngle, _settings.EndAngle, _totalAngle));
|
||||
float progression = Mathf.Clamp01(Mathf.InverseLerp(_settings.StartAngle, _settings.EndAngle, _state.TotalAngle));
|
||||
|
||||
_references.Stairs.transform.localPosition = new Vector3(0, _progression * _settings.Offset, 0);
|
||||
if (progression >= .5f && _state.Progression < .5f)
|
||||
{
|
||||
_events.OnTopReached?.Invoke();
|
||||
}
|
||||
else if (progression < .5f && _state.Progression >= .5f)
|
||||
{
|
||||
_events.OnBottomReached?.Invoke();
|
||||
}
|
||||
|
||||
_state.Progression = progression;
|
||||
|
||||
_references.Stairs.transform.localPosition = new Vector3(0, _state.Progression * _settings.Offset, 0);
|
||||
}
|
||||
|
||||
private void ManageInside()
|
||||
{
|
||||
foreach (GameObject obj in _references.Inside) obj.SetActive(_playerInside);
|
||||
foreach (GameObject obj in _references.Outside) obj.SetActive(!_playerInside);
|
||||
foreach (GameObject obj in _references.Inside) obj.SetActive(_state.PlayerInside);
|
||||
foreach (GameObject obj in _references.Outside) obj.SetActive(!_state.PlayerInside);
|
||||
|
||||
Shader.SetGlobalFloat("_MaskEnabled", _playerInside ? 0 : 1);
|
||||
_events.OnInside?.Invoke(_state.PlayerInside);
|
||||
|
||||
/*Shader.SetGlobalFloat("_MaskEnabled", _state.PlayerInside ? 0 : 1);
|
||||
|
||||
foreach (var feature in _references.RendererData.rendererFeatures)
|
||||
{
|
||||
@@ -114,9 +208,9 @@ public class SpiralStaircase : MonoBehaviour
|
||||
|
||||
if (feature.name == "HiddenThroughMask")
|
||||
{
|
||||
feature.SetActive(!_playerInside);
|
||||
feature.SetActive(!_state.PlayerInside);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user