Initial commit
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user