using System; using System.Collections.Generic; using BitStrap; using UnityEngine; public class VRTeleport : MonoBehaviour { public FishingPlayer fishingPlayer; public Transform headTransform; [ReadOnly] public Transform handTransform; public Transform gazeTarget; public LayerMask surfaceLayers; [Header("Gaze")] public float gazeMaxDistance = 20f; public Vector3 gazeHeightModifier = new Vector3(0f, -0.5f, 0f); private RaycastHit hit; [Header("Pointer")] public Transform pointerTarget; public Transform pointerDirection; public LineRenderer pointerLineRenderer; public float pointerMaxDistance = 20f; public float pointerThumbstickMagnitude = 0.4f; [ReadOnly] public float lastTeleportAngle; public float maxTeleportHitAngle = 40f; [Header("Visuals")] public Color defaultColor = Color.blue; public Color activeColor = Color.red; public List materialsToColor = new List(); [ReadOnly] public bool canTeleport; [Tooltip("Maximum range for aiming.")] [Header("Arch")] public float Range = 30f; [Tooltip("The MinimumElevation is relative to the AimPosition.")] public float MinimumElevation = -1f; [Tooltip("The Gravity is used in conjunction with AimVelocity and the aim direction to simulate a projectile.")] public float Gravity = -9.8f; [Range(0.001f, 50f)] [Tooltip("The AimVelocity is the initial speed of the faked projectile.")] public float AimVelocity = 1.5f; [Range(0.001f, 1f)] [Tooltip("The AimStep is the how much to subdivide the iteration.")] public float AimStep = 0.2f; private List points = new List(); private void Start() { gazeTarget.gameObject.SetActive(false); pointerTarget.gameObject.SetActive(false); pointerLineRenderer.enabled = false; ChangePointerColor(false); } private void LateUpdate() { if (!VRManager.IsVROn() || !VRManager.Instance || ((bool)TutorialManager.Instance && (bool)TutorialManager.Instance.currentTutorial) || VRManager.Instance.playerWalkStyle == VRManager.PlayerWalkStyle.FREE || ((bool)GameController.Instance && GameController.Instance.IsQuickMenu())) { return; } if (VRManager.Instance.playerWalkStyle == VRManager.PlayerWalkStyle.GAZE_TELEPORT) { canTeleport = false; Debug.DrawRay(headTransform.position + gazeHeightModifier, headTransform.forward * hit.distance, Color.blue); if (Physics.Raycast(headTransform.position + gazeHeightModifier, headTransform.forward, out hit, gazeMaxDistance, surfaceLayers)) { canTeleport = CheckHitTarget(hit); } if (fishingPlayer.currentState == FishingPlayer.PlayerState.DRILLING || fishingPlayer.currentState == FishingPlayer.PlayerState.DRIVING_BOAT || fishingPlayer.currentState == FishingPlayer.PlayerState.ICE_FISHING || fishingPlayer.currentState == FishingPlayer.PlayerState.WATCH_FISH) { canTeleport = false; } if (canTeleport) { gazeTarget.gameObject.SetActive(true); gazeTarget.position = hit.point; gazeTarget.rotation = Quaternion.LookRotation(hit.normal); if (UtilitiesInput.GetButtonDown("VR_TELEPORT_GAZE") || OVRInput.GetDown(OVRInput.Button.PrimaryThumbstickUp, OVRInput.Controller.Gamepad)) { ChangePointerColor(true); } if (UtilitiesInput.GetButtonUp("VR_TELEPORT_GAZE") || OVRInput.GetUp(OVRInput.Button.PrimaryThumbstickUp, OVRInput.Controller.Gamepad)) { ChangePointerColor(false); } if (gazeTarget.gameObject.activeSelf && (UtilitiesInput.GetButtonUp("VR_TELEPORT_GAZE") || OVRInput.GetUp(OVRInput.Button.PrimaryThumbstickUp, OVRInput.Controller.Gamepad) || UtilitiesInput.isLThumbstickUp)) { MakeTeleport(gazeTarget); } } else { gazeTarget.gameObject.SetActive(false); } } Vector2 vector = OVRInput.Get(OVRInput.Axis2D.PrimaryThumbstick, VRControllersManager.Instance.GetSecondaryController()); float vectorAngle = Utilities.GetVectorAngle(vector); vectorAngle += fishingPlayer.ufpsCamera.transform.eulerAngles.y; if (VRManager.Instance.playerWalkStyle != VRManager.PlayerWalkStyle.POINTER_TELEPORT || (!(vector.magnitude > pointerThumbstickMagnitude) && !pointerTarget.gameObject.activeSelf)) { return; } canTeleport = false; handTransform = VRControllersManager.Instance.GetVRController(VRControllersManager.Instance.GetSecondaryController()).pointerTeleportTransform; if (handTransform != null) { } if (fishingPlayer.currentState == FishingPlayer.PlayerState.DRILLING || fishingPlayer.currentState == FishingPlayer.PlayerState.DRIVING_BOAT || fishingPlayer.currentState == FishingPlayer.PlayerState.ICE_FISHING || fishingPlayer.currentState == FishingPlayer.PlayerState.WATCH_FISH) { canTeleport = false; } else if (handTransform != null) { canTeleport = CheckPointerTeleport(new Ray(handTransform.position, handTransform.forward)); } if (canTeleport) { pointerLineRenderer.enabled = true; pointerTarget.gameObject.SetActive(true); pointerTarget.position = hit.point; pointerTarget.rotation = Quaternion.LookRotation(hit.normal); if (pointerTarget.gameObject.activeSelf && vector.magnitude < pointerThumbstickMagnitude) { pointerTarget.eulerAngles = new Vector3(pointerTarget.eulerAngles.x, lastTeleportAngle - fishingPlayer.ufpsCamera.transform.localEulerAngles.y, pointerTarget.eulerAngles.z); MakeTeleport(pointerTarget); pointerLineRenderer.enabled = false; pointerTarget.gameObject.SetActive(false); } else { pointerDirection.eulerAngles = new Vector3(0f, vectorAngle, 0f); pointerDirection.localEulerAngles = new Vector3(0f, pointerDirection.localEulerAngles.y, 0f); lastTeleportAngle = vectorAngle; } } else { pointerLineRenderer.enabled = false; pointerTarget.gameObject.SetActive(false); } } public void RefreshTeleportStyle() { canTeleport = false; gazeTarget.gameObject.SetActive(false); pointerTarget.gameObject.SetActive(false); pointerLineRenderer.enabled = false; } private void MakeTeleport(Transform target) { fishingPlayer.GetComponent().MakeFootstep(); target.position += Vector3.up * 0.05f; Vector3 newRotation = new Vector3(fishingPlayer.transform.eulerAngles.x, target.eulerAngles.y, fishingPlayer.transform.eulerAngles.z); if ((bool)fishingPlayer.boatSimulator) { fishingPlayer.characteController.enabled = false; if (VRManager.Instance.teleportStyle == VRManager.TeleportStyle.INSTANT) { LeanTween.delayedCall(0.1f, (Action)delegate { if (VRManager.Instance.playerWalkStyle == VRManager.PlayerWalkStyle.POINTER_TELEPORT) { fishingPlayer.SetPositionAndRotation(target.position, newRotation); } else { fishingPlayer.SetPosition(target.position); } }); LeanTween.delayedCall(0.2f, (Action)delegate { fishingPlayer.characteController.enabled = true; }); } else if (VRManager.Instance.teleportStyle == VRManager.TeleportStyle.FADE) { if (VRManager.Instance.playerWalkStyle == VRManager.PlayerWalkStyle.POINTER_TELEPORT) { StartCoroutine(fishingPlayer.SetPositionAndRotationFade(target.position, newRotation, VRManager.Instance.fadeDuration)); } else { StartCoroutine(fishingPlayer.SetPositionFade(target.position, VRManager.Instance.fadeDuration)); } LeanTween.delayedCall(VRManager.Instance.fadeDuration + 0.2f, (Action)delegate { fishingPlayer.characteController.enabled = true; }); } } else if (VRManager.Instance.teleportStyle == VRManager.TeleportStyle.INSTANT || !fishingPlayer.enabled) { if (VRManager.Instance.playerWalkStyle == VRManager.PlayerWalkStyle.POINTER_TELEPORT) { fishingPlayer.SetPositionAndRotation(target.position, newRotation); } else { fishingPlayer.SetPosition(target.position); } } else if (VRManager.Instance.teleportStyle == VRManager.TeleportStyle.FADE) { if (VRManager.Instance.playerWalkStyle == VRManager.PlayerWalkStyle.POINTER_TELEPORT) { StartCoroutine(fishingPlayer.SetPositionAndRotationFade(target.position, newRotation, VRManager.Instance.fadeDuration)); } else { StartCoroutine(fishingPlayer.SetPositionFade(target.position, VRManager.Instance.fadeDuration)); } } } private bool CheckHitTarget(RaycastHit raycastHit) { if ((bool)GameController.Instance && raycastHit.point.y < -1f) { return false; } if (Vector3.Angle(raycastHit.normal, Vector3.up) > maxTeleportHitAngle) { return false; } if (!raycastHit.collider.gameObject.HasTag("TELEPORT")) { return false; } if ((bool)fishingPlayer.boatSimulator && raycastHit.collider.GetComponentInParent() != fishingPlayer.boatSimulator) { return false; } return true; } public bool CheckPointerTeleport(Ray startRay) { points.Clear(); Vector3 origin = startRay.origin; Vector3 vector = startRay.direction * AimVelocity; float num = Range * Range; bool result = false; do { points.Add(origin); Vector3 vector2 = vector; vector2.y += Gravity * (1f / 90f) * AimStep; vector = vector2; origin += vector2 * AimStep; if (Physics.Raycast(origin, vector, out hit, 0.8f, surfaceLayers)) { if (CheckHitTarget(hit) && !hit.collider.GetComponent()) { result = true; } break; } } while (origin.y - startRay.origin.y > MinimumElevation && (startRay.origin - origin).sqrMagnitude <= num); pointerLineRenderer.positionCount = points.Count; for (int i = 0; i < points.Count; i++) { pointerLineRenderer.SetPosition(i, points[i]); } return result; } public void ChangePointerColor(bool active) { Color color = ((!active) ? defaultColor : activeColor); for (int i = 0; i < materialsToColor.Count; i++) { color.a = materialsToColor[i].color.a; materialsToColor[i].color = color; } } }