using OctoCore; using UnityEngine; namespace Unheimlich.NonEuclidean { public class NonEuclideanPortal : MonoBehaviour { [System.Serializable] private class References { public NonEuclideanRoom OwnRoom; public NonEuclideanRoom TragetRoom; } [System.Serializable] private class State { [OctoReadOnly] public bool Active; } [SerializeField] private References _references; [SerializeField] private State _state; public NonEuclideanRoom OwnRoom => _references.OwnRoom; public NonEuclideanRoom TargetRoom => _references.TragetRoom; private void OnDrawGizmos() { Gizmos.color = _state.Active ? new Color(0, 1, 1) : new Color(1, 1, 0); Gizmos.matrix = transform.localToWorldMatrix; Gizmos.DrawWireCube(Vector3.zero, new Vector3(1, 1, 0)); Gizmos.DrawLine(new Vector3(0, -.4f, -.1f), new Vector3(0, -.4f, -.6f)); Gizmos.DrawLine(new Vector3(0, -.4f, -.1f), new Vector3(.2f, -.4f, -.3f)); Gizmos.DrawLine(new Vector3(0, -.4f, -.1f), new Vector3(-.2f, -.4f, -.3f)); } void OnDisable() { //if (_state.Active) //{ // Shader.SetGlobalMatrix("_PortalMatrix", Matrix4x4.identity); // Shader.SetGlobalMatrix("_CameraMatrix", Matrix4x4.identity); //} } public bool IsPortalPassed() { if (_state.Active && NonEuclideanManager.Instance && NonEuclideanManager.Instance.Camera) { Shader.SetGlobalMatrix("_PortalMatrix", transform.worldToLocalMatrix); Shader.SetGlobalMatrix("_CameraMatrix", NonEuclideanManager.Instance.Camera.transform.localToWorldMatrix); if (IsInsidePortalFrame(NonEuclideanManager.Instance.Camera)) { Debug.Log($"Portal: {name} has been passed ({NonEuclideanManager.Instance.ActiveRoom.name} → {_references.TragetRoom.name})."); NonEuclideanManager.Instance.SetActiveRoom(_references.TragetRoom); return true; } } return false; } public void Activate(bool activate) { if (!NonEuclideanManager.Instance || !NonEuclideanManager.Instance.ActiveRoom) { _state.Active = false; return; } _state.Active = activate; } private bool IsInsidePortalFrame(Camera camera) { Vector3 localCamPos = transform.InverseTransformPoint(camera.transform.position); bool isInside = Mathf.Abs(localCamPos.x) < transform.localScale.x * .5f && Mathf.Abs(localCamPos.y) < transform.localScale.y * .5f && localCamPos.z > 0 && localCamPos.z < transform.localScale.x * .5f; return isInside; } } }