You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			158 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C#
		
	
		
		
			
		
	
	
			158 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C#
		
	
| 
								 
											1 year ago
										 
									 | 
							
								using System.Collections;
							 | 
						||
| 
								 | 
							
								using System.Collections.Generic;
							 | 
						||
| 
								 | 
							
								using UnityEngine;
							 | 
						||
| 
								 | 
							
								using UnityEngine.Events;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace Autohand{
							 | 
						||
| 
								 | 
							
								    [HelpURL("https://app.gitbook.com/s/5zKO0EvOjzUDeT2aiFk3/auto-hand/teleportation")]
							 | 
						||
| 
								 | 
							
								    public class Teleporter : MonoBehaviour{
							 | 
						||
| 
								 | 
							
								        [Header("Teleport")]
							 | 
						||
| 
								 | 
							
								        [Tooltip("The object to teleport")]
							 | 
						||
| 
								 | 
							
								        public GameObject teleportObject;
							 | 
						||
| 
								 | 
							
								        [Tooltip("Can be left empty - Used for if there is a container that should be teleported in addition to the main teleport object")]
							 | 
						||
| 
								 | 
							
								        public Transform[] additionalTeleports;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        [Header("Aim Settings")]
							 | 
						||
| 
								 | 
							
								        [Tooltip("The Object to Shoot the Beam From")]
							 | 
						||
| 
								 | 
							
								        public Transform aimer;
							 | 
						||
| 
								 | 
							
								        [Tooltip("Layers You Can Teleport On")]
							 | 
						||
| 
								 | 
							
								        public LayerMask layer;
							 | 
						||
| 
								 | 
							
								        [Tooltip("The Maximum Slope You Can Teleport On")]
							 | 
						||
| 
								 | 
							
								        public float maxSurfaceAngle = 45;
							 | 
						||
| 
								 | 
							
								        [Min(0)]
							 | 
						||
| 
								 | 
							
								        public float distanceMultiplyer = 1;
							 | 
						||
| 
								 | 
							
								        [Min(0)]
							 | 
						||
| 
								 | 
							
								        public float curveStrength = 1;
							 | 
						||
| 
								 | 
							
								        [Tooltip("Use Worldspace Must be True")]
							 | 
						||
| 
								 | 
							
								        public LineRenderer line;
							 | 
						||
| 
								 | 
							
								        [Tooltip("Maximum Length of The Teleport Line")]
							 | 
						||
| 
								 | 
							
								        public int lineSegments = 50;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								        [Header("Line Settings")]
							 | 
						||
| 
								 | 
							
								        public Gradient canTeleportColor = new Gradient(){ colorKeys = new GradientColorKey[] { new GradientColorKey(){ color = Color.green, time = 0 } } };
							 | 
						||
| 
								 | 
							
								        public Gradient cantTeleportColor = new Gradient(){ colorKeys = new GradientColorKey[] { new GradientColorKey(){ color = Color.red, time = 0 } } };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        [Tooltip("This gameobject will match the position of the teleport point when aiming")]
							 | 
						||
| 
								 | 
							
								        public GameObject indicator;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        [Header("Unity Events")]
							 | 
						||
| 
								 | 
							
								        public UnityEvent OnStartTeleport;
							 | 
						||
| 
								 | 
							
								        public UnityEvent OnStopTeleport;
							 | 
						||
| 
								 | 
							
								        public UnityEvent OnTeleport;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Vector3[] lineArr;
							 | 
						||
| 
								 | 
							
								        bool aiming;
							 | 
						||
| 
								 | 
							
								        bool hitting;
							 | 
						||
| 
								 | 
							
								        RaycastHit aimHit;
							 | 
						||
| 
								 | 
							
								        HandTeleportGuard[] teleportGuards;
							 | 
						||
| 
								 | 
							
								        AutoHandPlayer playerBody;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private void Awake() {
							 | 
						||
| 
								 | 
							
								            line.enabled = false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private void Start() {
							 | 
						||
| 
								 | 
							
								            playerBody = AutoHandExtensions.CanFindObjectOfType<AutoHandPlayer>();
							 | 
						||
| 
								 | 
							
								            if (playerBody != null && playerBody.transform.gameObject == teleportObject)
							 | 
						||
| 
								 | 
							
								                teleportObject = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            lineArr = new Vector3[lineSegments];
							 | 
						||
| 
								 | 
							
								            teleportGuards = AutoHandExtensions.CanFindObjectsOfType<HandTeleportGuard>();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        void Update(){
							 | 
						||
| 
								 | 
							
								            if(aiming)
							 | 
						||
| 
								 | 
							
								                CalculateTeleport();
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								                line.positionCount = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            DrawIndicator();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        void CalculateTeleport() {
							 | 
						||
| 
								 | 
							
								            line.colorGradient = cantTeleportColor;
							 | 
						||
| 
								 | 
							
								            var lineList = new List<Vector3>();
							 | 
						||
| 
								 | 
							
								            int i;
							 | 
						||
| 
								 | 
							
								            hitting = false;
							 | 
						||
| 
								 | 
							
								            for(i = 0; i < lineSegments; i++) {
							 | 
						||
| 
								 | 
							
								                var time = i/60f;
							 | 
						||
| 
								 | 
							
								                lineArr[i] = aimer.transform.position;
							 | 
						||
| 
								 | 
							
								                lineArr[i] += transform.forward*time*distanceMultiplyer*15;
							 | 
						||
| 
								 | 
							
								                lineArr[i].y += curveStrength * (time - Mathf.Pow(9.8f*0.5f*time, 2));
							 | 
						||
| 
								 | 
							
								                lineList.Add(lineArr[i]);
							 | 
						||
| 
								 | 
							
								                if(i != 0) {
							 | 
						||
| 
								 | 
							
								                    if(Physics.Raycast(lineArr[i-1], lineArr[i]-lineArr[i-1], out aimHit, Vector3.Distance(lineArr[i], lineArr[i-1]), ~Hand.GetHandsLayerMask(), QueryTriggerInteraction.Ignore)) {
							 | 
						||
| 
								 | 
							
								                        //Makes sure the angle isnt too steep
							 | 
						||
| 
								 | 
							
								                        if(Vector3.Angle(aimHit.normal, Vector3.up) <= maxSurfaceAngle && layer == (layer | (1 << aimHit.collider.gameObject.layer))) {
							 | 
						||
| 
								 | 
							
								                            line.colorGradient = canTeleportColor;
							 | 
						||
| 
								 | 
							
								                            lineList.Add(aimHit.point);
							 | 
						||
| 
								 | 
							
								                            hitting = true;
							 | 
						||
| 
								 | 
							
								                            break;
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            line.enabled = true;
							 | 
						||
| 
								 | 
							
								            line.positionCount = i;
							 | 
						||
| 
								 | 
							
								            line.SetPositions(lineArr);
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        void DrawIndicator(){
							 | 
						||
| 
								 | 
							
								            if(indicator != null){
							 | 
						||
| 
								 | 
							
								                if(hitting){
							 | 
						||
| 
								 | 
							
								                    indicator.gameObject.SetActive(true);
							 | 
						||
| 
								 | 
							
								                    indicator.transform.position = aimHit.point;
							 | 
						||
| 
								 | 
							
								                    indicator.transform.up = aimHit.normal;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else
							 | 
						||
| 
								 | 
							
								                    indicator.gameObject.SetActive(false);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void StartTeleport(){
							 | 
						||
| 
								 | 
							
								            aiming = true;
							 | 
						||
| 
								 | 
							
								            OnStartTeleport?.Invoke();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void CancelTeleport(){
							 | 
						||
| 
								 | 
							
								            line.positionCount = 0;
							 | 
						||
| 
								 | 
							
								            line.enabled = false;
							 | 
						||
| 
								 | 
							
								            hitting = false;
							 | 
						||
| 
								 | 
							
								            aiming = false;
							 | 
						||
| 
								 | 
							
								            OnStopTeleport?.Invoke();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void Teleport(){
							 | 
						||
| 
								 | 
							
								            Queue<Vector3> fromPos = new Queue<Vector3>();
							 | 
						||
| 
								 | 
							
								            foreach(var guard in teleportGuards) {
							 | 
						||
| 
								 | 
							
								                if(guard.gameObject.activeInHierarchy)
							 | 
						||
| 
								 | 
							
								                    fromPos.Enqueue(guard.transform.position);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(hitting) {
							 | 
						||
| 
								 | 
							
								                if (teleportObject != null){
							 | 
						||
| 
								 | 
							
								                    var diff = aimHit.point - teleportObject.transform.position;
							 | 
						||
| 
								 | 
							
								                    teleportObject.transform.position = aimHit.point;
							 | 
						||
| 
								 | 
							
								                    foreach (var teleport in additionalTeleports){
							 | 
						||
| 
								 | 
							
								                        teleport.position += diff;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                playerBody?.SetPosition(aimHit.point);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								               OnTeleport?.Invoke();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                foreach(var guard in teleportGuards) {
							 | 
						||
| 
								 | 
							
								                    if(guard.gameObject.activeInHierarchy) {
							 | 
						||
| 
								 | 
							
								                        guard.TeleportProtection(fromPos.Dequeue(), guard.transform.position);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            CancelTeleport();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |