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#
		
	
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();
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |