111 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections;
 | |
| using System.Collections.Generic;
 | |
| using System.Runtime.InteropServices;
 | |
| using Unity.XR.CoreUtils;
 | |
| using UnityEngine;
 | |
| using UnityEngine.Rendering.Universal;
 | |
| 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)
 | |
|     {
 | |
|         //Debug.Log("Something entered portal");
 | |
|         if (other.GetComponent<UniversalAdditionalCameraData>() == null) return;
 | |
|         //if (other.GetComponent<XROrigin>() == null) return;
 | |
|         XROrigin player = other.GetComponentInParent<XROrigin>();
 | |
|         if (player == 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, player.transform.position);
 | |
|             Quaternion targetRotation = TransformRotationBetweenPortals(this, targetPortal, player.transform.rotation);
 | |
| 
 | |
|             TeleportRequest request = new TeleportRequest
 | |
|             {
 | |
|                 destinationPosition = targetPosition,
 | |
|                 destinationRotation = targetRotation,
 | |
|                 matchOrientation = MatchOrientation.TargetUpAndForward
 | |
|             };
 | |
| 
 | |
| 
 | |
|             teleportationProvider.QueueTeleportRequest(request);
 | |
| 
 | |
|             player.transform.rotation = TransformRotationBetweenPortals(this, targetPortal, player.transform.rotation);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             Debug.LogWarning("TeleportationProvider is not assigned!", this);
 | |
|             player.transform.position = TransformPositionBetweenPortals(this, targetPortal, player.transform.position);
 | |
|             player.transform.rotation = TransformRotationBetweenPortals(this, targetPortal, player.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;
 | |
| }
 |