using OctoCore; using UnityEngine; using UnityEngine.SocialPlatforms; [ExecuteInEditMode, DefaultExecutionOrder(0)] public class PortalManager : MonoBehaviour { public static PortalManager Instance { get; private set; } [System.Serializable] public class State { public bool PlayerInside; public Portal[] Portals; } [SerializeField, OctoReadOnly] private State _state; void OnEnable() { _state = new State(); _state.Portals = new Portal[3]; if (!Instance) Instance = this; ResetMasks(); } void OnDisable() { if (Instance == this) Instance = null; ResetMasks(); } void Update() { UpdateMasks(); } public void SetInside(bool inside) { _state.PlayerInside = inside; UpdateMasks(); } public void RegisterPortal(Portal portal) { _state.Portals[portal.ID] = portal; ManageMask(portal, true); } public void UnregisterPortal(Portal portal) { ManageMask(portal, false); _state.Portals[portal.ID] = null; } public void ManageMask(Portal portal, bool active) { if (!portal) return; if (_state.Portals[portal.ID] != portal) { RegisterPortal(portal); return; } Vector3 camPos = Camera.main ? Camera.main.transform.position : Vector3.zero; Matrix4x4 m = new Matrix4x4(); m.SetRow(0, new Vector4(camPos.x, camPos.y, camPos.z, !active || _state.PlayerInside ? 0 : 1)); m.SetRow(1, new Vector4(portal.transform.position.x, portal.transform.position.y, portal.transform.position.z, portal.Oval)); m.SetRow(2, new Vector4(portal.transform.up.x, portal.transform.up.y, portal.transform.up.z, portal.transform.localScale.x)); m.SetRow(3, new Vector4(portal.transform.forward.x, portal.transform.forward.y, portal.transform.forward.z, portal.transform.localScale.y)); SetMask(portal.ID, m); } private void UpdateMasks() { for (int i = 0; i < _state.Portals.Length; i++) ManageMask(_state.Portals[i], true); } private void ResetMasks() { for (int i = 0; i < _state.Portals.Length; i++) { Matrix4x4 m = new Matrix4x4(); m.SetRow(0, Vector4.zero); m.SetRow(1, Vector4.zero); m.SetRow(2, Vector4.zero); m.SetRow(3, Vector4.zero); SetMask(i, m); } } private void SetMask(int id, Matrix4x4 m) { Shader.SetGlobalMatrix($"_Mask{id}", m); } }