Files
Ipseity-Demo/Assets/_Content/Scripts/Features/Portal/PortalManager.cs
T

111 lines
2.6 KiB
C#

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);
}
}