102 lines
3.4 KiB
C#
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;
|
|
}
|