102 lines
3.4 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Unity.XR.CoreUtils;
using UnityEngine;
using UnityEngine.XR;
using UnityEngine.XR.Interaction.Toolkit;
public class StencilPortal : MonoBehaviour
{
public bool destroyAfterTeleport;
public StencilPortal targetPortal;
public Transform normalVisible;
public Transform normalInvisible;
public LayerMask defaultLayer;
public LayerMask portalLayer;
public PortalScene portalScene;
public OcclusionPortal occlusionPortal;
public bool _shouldTeleport;
public TeleportationProvider teleportationProvider; // Reference to TeleportationProvider
public static Vector3 TransformPositionBetweenPortals(StencilPortal sender, StencilPortal target, Vector3 position)
{
return target.normalInvisible.TransformPoint(sender.normalVisible.InverseTransformPoint(position));
}
public static Quaternion TransformRotationBetweenPortals(StencilPortal sender, StencilPortal target, Quaternion rotation)
{
return target.normalInvisible.rotation * Quaternion.Inverse(sender.normalVisible.rotation) * rotation;
}
private void OnTriggerEnter(Collider other)
{
if (other.GetComponent<XROrigin>() == null) return;
if (occlusionPortal != null)
{
occlusionPortal.open = !occlusionPortal.open;
}
if (!_shouldTeleport)
{
if (destroyAfterTeleport)
{
Destroy(gameObject, 0.5f);
}
return;
}
Debug.Log(transform.name + " player entered and should teleport");
targetPortal._shouldTeleport = false;
if (teleportationProvider != null)
{
Vector3 targetPosition = TransformPositionBetweenPortals(this, targetPortal, other.transform.position);
Quaternion targetRotation = TransformRotationBetweenPortals(this, targetPortal, other.transform.rotation);
TeleportRequest request = new TeleportRequest
{
destinationPosition = targetPosition,
destinationRotation = targetRotation,
matchOrientation = MatchOrientation.TargetUpAndForward
};
teleportationProvider.QueueTeleportRequest(request);
other.transform.rotation = TransformRotationBetweenPortals(this, targetPortal, other.transform.rotation);
}
else
{
Debug.LogWarning("TeleportationProvider is not assigned!", this);
other.transform.position = TransformPositionBetweenPortals(this, targetPortal, other.transform.position);
other.transform.rotation = TransformRotationBetweenPortals(this, targetPortal, other.transform.rotation);
}
if (destroyAfterTeleport)
{
Destroy(gameObject, 0.5f);
}
}
private void OnTriggerExit(Collider other)
{
AllowTeleport();
if (!_shouldTeleport || IsInvoking(nameof(AllowTeleport))) return;
if (!other.CompareTag("Player")) return;
Debug.Log(transform.name + " player exited");
Invoke(nameof(AllowTeleport), 1f);
}
private void AllowTeleport()
{
_shouldTeleport = true;
}
public StencilPortal TargetPortal => targetPortal;
public LayerMask DefaultLayer => defaultLayer;
public LayerMask PortalLayer => portalLayer;
}