Initial commit

This commit is contained in:
Thorbjoern
2025-05-26 00:46:28 +02:00
commit e5bca03433
3896 changed files with 1434297 additions and 0 deletions
@@ -0,0 +1,253 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Fragilem17.MirrorsAndPortals
{
/**
* Used to transport PortalableObjects to the linked portal defined in the portalSurface
*/
public class PortalTransporter : MonoBehaviour
{
private Portal _portal;
public List<PortalableObject> portalableObjects = new List<PortalableObject>();
//private List<CloneRenderer> cloneObjects = new List<CloneRenderer>();
public HashSet<CloneRenderer> cloneObjects = new HashSet<CloneRenderer>();
public HashSet<CloneRenderer> cloneObjectsActuallyTouching = new HashSet<CloneRenderer>();
public HashSet<CloneRenderer> cloneObjectsToRemove = new HashSet<CloneRenderer>();
private List<PortalAffectorSphere> portalAffectorSpheres = new List<PortalAffectorSphere>();
private Vector3 _originalScale;
[Space(10)]
[Header("Events")]
public UnityEvent<PortalableObject> OnObjectEnteredPortal;
public UnityEvent<PortalableObject> OnObjectTransportedAwayFromHere;
public UnityEvent<PortalableObject> OnObjectTransportedToHere;
public UnityEvent<PortalableObject> OnObjectExitedPortal;
[HideInInspector]
public Collider MyCollider;
public enum PortalReason {
Undefined,
ExitedCurrentPortalCollider,
EnteredOtherPortalCollider
}
public Portal Portal { get => _portal; }
public void Initialise()
{
MyCollider = GetComponent<Collider>();
if (!MyCollider)
{
Debug.LogWarning(PortalUtils.Colorize("[PORTALS] ", PortalUtils.DebugColors.Warn, true) + name + " has a PortalTransporter Component but no trigger Collider, add a big enough Collider for things to hit it before reaching the actual portal.");
}
else
{
MyCollider.isTrigger = true;
}
Rigidbody rb = GetComponent<Rigidbody>();
if (!rb)
{
Debug.LogWarning(PortalUtils.Colorize("[PORTALS] ", PortalUtils.DebugColors.Warn, true) + name + " has a PortalTransporter Component but no RigidBody Component. Add a (Kinematic) Rigidbody Component to this GameObject.");
}
_portal = GetComponentInParent<Portal>();
if (!_portal)
{
Debug.LogWarning(PortalUtils.Colorize("[PORTALS] ", PortalUtils.DebugColors.Warn, true) + name + " has a PortalTransporter Component but no Portal Component, add a Portal Component to this or a parent GameObject.");
}
}
protected void OnEnable()
{
Initialise();
}
private void FixedUpdate()
{
//CheckNeedPortal();
}
private void LateUpdate()
{
//CheckNeedPortal();
}
protected void Update()
{
CheckNeedPortal();
}
protected void CheckNeedPortal()
{
PortalableObject p = null;
for (int i = 0; i < portalableObjects.Count; ++i)
{
p = portalableObjects[i];
if (p)
{
Vector3 objPos = _portal.PortalSurface.transform.InverseTransformPoint(p.transform.position);
if (objPos.z > 0)
{
PortalableObject po = portalableObjects[i];
if (po.CanPortal())
{
//Debug.Log("PortalTransporter " + Portal.name + " : fixedUpdate z > 0 - doing portal on " + po.name + " : " + objPos.z);
if (_portal.OtherPortal && _portal.OtherPortal.PortalTransporter)
{
// only trigger the ExternalTriggerEnter if we're actually telepoting inside our collider!
_portal.OtherPortal.PortalTransporter.ExternalTriggerEnter(po.gameObject, false);
_portal.OtherPortal.PortalTransporter.OnObjectTransportedToHere.Invoke(po);
}
po.PortalFrom(_portal);
OnObjectTransportedAwayFromHere.Invoke(po);
}
}
}
}
}
public void ExternalTriggerEnter(GameObject other, bool fromPhysics = false)
{
// first trigger the exit in the other portal
if (!fromPhysics && _portal.OtherPortal && _portal.OtherPortal.PortalTransporter)
{
_portal.OtherPortal.PortalTransporter.ExternalTriggerExit(other, fromPhysics, PortalReason.EnteredOtherPortalCollider);
}
Vector3 objPos = _portal.PortalSurface.transform.InverseTransformPoint(other.transform.position);
// did we enter in front of the portal?
//Debug.Log("ExternalTriggerEnter objPos: " + other.name + " " + objPos.z + " " + fromPhysics + " :" + Portal.name);
if (!fromPhysics || (fromPhysics && objPos.z < 0))
{
PortalableObject obj = other.GetComponent<PortalableObject>();
if (obj && obj.isActiveAndEnabled && !portalableObjects.Contains(obj))
{
//Debug.Log("Adding to portal list of " + _portal.name + " object:" + other.name);
portalableObjects.Add(obj);
//obj.OnExitPortalCollider.AddListener(onPortalableObjectExitPortalCollider);
obj.SetIsInPortal(_portal);
OnObjectEnteredPortal.Invoke(obj);
}
else
{
PortalableObjectCollider helper = other.GetComponent<PortalableObjectCollider>();
if (helper && helper.isActiveAndEnabled && !portalableObjects.Contains(helper.PortalableObject))
{
//Debug.Log("Adding to portal list of " + _portal.name + " object:" + other.name);
portalableObjects.Add(helper.PortalableObject);
//obj.OnExitPortalCollider.AddListener(onPortalableObjectExitPortalCollider);
helper.PortalableObject.SetIsInPortal(_portal);
OnObjectEnteredPortal.Invoke(helper.PortalableObject);
}
}
CloneRenderer cloneObject = other.GetComponent<CloneRenderer>();
if (cloneObject && cloneObject.isActiveAndEnabled && !cloneObjects.Contains(cloneObject))
{
cloneObjects.Add(cloneObject);
cloneObject.SetIsInPortal(_portal, true);
}
PortalAffectorSphere affectorSphere = other.GetComponent<PortalAffectorSphere>();
if (affectorSphere && affectorSphere.isActiveAndEnabled && !portalAffectorSpheres.Contains(affectorSphere))
{
//if (fromPhysics)
//{
portalAffectorSpheres.Add(affectorSphere);
//}
affectorSphere.SetIsInPortal(_portal);
}
}
}
/*private void onPortalableObjectExitPortalCollider(PortalableObject obj, Portal p)
{
if (p == Portal)
{
ExternalTriggerExit(obj.gameObject, false);
}
}*/
public void ExternalTriggerExit(GameObject other, bool fromPhysics = false, PortalReason reason = PortalReason.Undefined)
{
PortalableObject portalableObj = other.GetComponent<PortalableObject>();
/*
bool isPortallingAlongWithMasterPortalable = false;
if (portalableObj) {
//portalableObj.OnExitPortalCollider.RemoveListener(onPortalableObjectExitPortalCollider);
isPortallingAlongWithMasterPortalable = portalableObj.EnablePortalAlongWithMasterPortalable;
}
// todo: as long as we're grabbing something, and it's gonna portal along with the player, then don't exit the portal when it's collider exits this transporter.
// but, what to do when the player does not portal?
if (reason == PortalReason.ExitedCurrentPortalCollider && isPortallingAlongWithMasterPortalable)
{
// are we on the other side of the surface when exiting the collider? then keep it inside the portal
Vector3 objPos = _portal.PortalSurface.transform.InverseTransformPoint(other.transform.position);
Debug.Log("objPos: " + objPos.z);
if (objPos.z > 0)
{
return;
}
}*/
CloneRenderer cloneObject = other.GetComponent<CloneRenderer>();
/*if (cloneObject)
{
Debug.Log(cloneObject.name + " exits portal " + Portal.name + " IF " + cloneObjects.Contains(cloneObject) + " AND NOT isPortallingAlongWithMasterPortalable: " + isPortallingAlongWithMasterPortalable);
}*/
if (cloneObject && cloneObjects.Contains(cloneObject))
{
cloneObjects.Remove(cloneObject);
cloneObject.ExitPortal(_portal, fromPhysics);
}
if (portalableObj && portalableObjects.Contains(portalableObj))
{
//Debug.Log("Exit Portal " + gameObject.name);
//Debug.Log("Removing from portal list of " + _portal.name + " object:" + other.name);
//Debug.Log("PortalableObject " + portalableObj.name + " ExitsPortal: " + _portal.name + " fromPhysics: " + fromPhysics);
portalableObjects.Remove(portalableObj);
portalableObj.ExitPortal(_portal);
OnObjectExitedPortal.Invoke(portalableObj);
}
PortalAffectorSphere affectorSphere = other.GetComponent<PortalAffectorSphere>();
if (affectorSphere && portalAffectorSpheres.Contains(affectorSphere))
{
portalAffectorSpheres.Remove(affectorSphere);
affectorSphere.ExitPortal(_portal);
}
}
protected void OnTriggerEnter(Collider other)
{
//Debug.Log("OnTriggerEnter: " + other.name);
ExternalTriggerEnter(other.gameObject, true);
}
protected void OnTriggerExit(Collider other)
{
ExternalTriggerExit(other.gameObject, true, PortalReason.ExitedCurrentPortalCollider);
}
}
}