using UnityEngine; using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger; using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; namespace EscapeRoomEngine.Portal.Runtime { /// /// A portal driver is any object that can be teleported by a portal like the player, their hands or objects. /// [RequireComponent(typeof(Collider), typeof(Rigidbody))] public class PortalDriver : MonoBehaviour { /// /// The object that will be transported through the portal. Usually either this object or a parent offset object. /// If left empty, it will default to this object. /// public Transform traveller; /// /// Whether this portal driver has a clone mirroring it at other portals. Disable this for the player. /// public bool hasClone = true; /// /// Whether this portal driver is the player. Used by portals to tell when the player has passed to another space. /// public bool player; /// /// The side of the portal this became tracked on. /// [HideInInspector] public int entrySide; /// /// The clone that is used to mirror this portal driver at another portal. /// [HideInInspector] public PortalDriverClone clone; private Rigidbody _rigidbody; private void Awake() { // check whether the traveller is set if (!traveller) traveller = transform; // get the rigidbody if there is one _rigidbody = GetComponent(); } protected void Start() { if (hasClone) { clone = PortalDriverClone.Create(this); } } private void Update() { if (hasClone && clone.gameObject.activeSelf) { clone.UpdatePosition(transform); } } public void EnableClone(Portal at) { if (hasClone) { Logger.Log($"Enabled {clone} at {at}", LogType.Portals); clone.portal = at; clone.gameObject.SetActive(true); } } public void DisableClone(Portal at) { if (hasClone && at.Equals(clone.portal)) // don't disable clones that are already at a different portal { Logger.Log($"Disabled {clone} at {clone.portal}", LogType.Portals); clone.portal = null; clone.gameObject.SetActive(false); } } public void Teleport(Portal from, Portal to) { Logger.Log($"Teleported {this} from {from} to {to}", LogType.Portals); var m = to.portalTransform.localToWorldMatrix * Portal.HalfRotation * from.portalTransform.worldToLocalMatrix * traveller.localToWorldMatrix; traveller.SetPositionAndRotation(m.GetPosition(), m.rotation); if (_rigidbody && !_rigidbody.isKinematic) { _rigidbody.velocity = to.portalTransform.TransformDirection( Portal.HalfRotation.rotation * from.portalTransform.InverseTransformDirection(_rigidbody.velocity)); } } } }