123 lines
3.2 KiB
C#
123 lines
3.2 KiB
C#
using OctoCore.Components;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering.Universal;
|
|
|
|
public class SpiralStaircase : MonoBehaviour
|
|
{
|
|
[System.Serializable]
|
|
public class References
|
|
{
|
|
public UniversalRendererData RendererData;
|
|
public GameObject Stairs;
|
|
public GameObject[] Inside;
|
|
public GameObject[] Outside;
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class Settings
|
|
{
|
|
public float Offset = -12.25f;
|
|
public float StartAngle = 450;
|
|
public float EndAngle = 720;
|
|
}
|
|
|
|
[SerializeField] private References _references;
|
|
[SerializeField] private Settings _settings;
|
|
|
|
private bool _playerInside;
|
|
[SerializeField] private int _turns;
|
|
[SerializeField] private float _totalAngle;
|
|
[SerializeField] private float _progression;
|
|
|
|
void Start()
|
|
{
|
|
ManageInside();
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
_playerInside = false;
|
|
ManageInside();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (_playerInside)
|
|
Count();
|
|
}
|
|
|
|
void OnTriggerEnter(Collider col)
|
|
{
|
|
if (OctoPlayer.Instance && OctoPlayer.Instance.gameObject == col.gameObject)
|
|
{
|
|
if (!_playerInside)
|
|
{
|
|
_playerInside = true;
|
|
ManageInside();
|
|
}
|
|
}
|
|
}
|
|
|
|
void OnTriggerExit(Collider col)
|
|
{
|
|
if (OctoPlayer.Instance && OctoPlayer.Instance.gameObject == col.gameObject)
|
|
{
|
|
if (_playerInside)
|
|
{
|
|
_playerInside = false;
|
|
ManageInside();
|
|
}
|
|
}
|
|
}
|
|
|
|
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];
|
|
|
|
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);
|
|
|
|
if (quarterAngle > 90 && quarterAngle < 100)
|
|
{
|
|
_turns++;
|
|
}
|
|
else if (quarterAngle < 0 && _turns > 0)
|
|
{
|
|
_turns--;
|
|
}
|
|
|
|
_progression = Mathf.Clamp01(Mathf.InverseLerp(_settings.StartAngle, _settings.EndAngle, _totalAngle));
|
|
|
|
_references.Stairs.transform.localPosition = new Vector3(0, _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);
|
|
|
|
Shader.SetGlobalFloat("_MaskEnabled", _playerInside ? 0 : 1);
|
|
|
|
foreach (var feature in _references.RendererData.rendererFeatures)
|
|
{
|
|
// Stencil Mask
|
|
// VisibleThroughMask
|
|
// HiddenThroughMask
|
|
|
|
if (feature.name == "HiddenThroughMask")
|
|
{
|
|
feature.SetActive(!_playerInside);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|