using System.Collections; using System.Collections.Generic; using UnityEngine; using System; public class CameraController : MonoBehaviour { [Header("Налаштування польоту")] public float flightDuration = 4f; public AnimationCurve flightCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); [Header("Фінальна позиція відносно планети")] public Vector3 finalOffset = new Vector3(100f, 20f, -40f); public Vector3 finalRotation = new Vector3(8f, -70f, 0f); private bool isFlying = false; private Vector3 savedPosition; private Quaternion savedRotation; public void SavePosition() { savedPosition = transform.position; savedRotation = transform.rotation; } public void FlyToSavedPosition(System.Action onArrived = null) { StopAllCoroutines(); StartCoroutine(FlyToSavedCoroutine(onArrived)); } IEnumerator FlyToSavedCoroutine(System.Action onArrived) { Vector3 startPos = transform.position; Quaternion startRot = transform.rotation; Vector3 mid = Vector3.Lerp(startPos, savedPosition, 0.5f); mid += Vector3.up * Vector3.Distance(startPos, savedPosition) * 0.3f; float elapsed = 0f; while (elapsed < flightDuration) { elapsed += Time.deltaTime; float t = flightCurve.Evaluate(elapsed / flightDuration); Vector3 p1 = Vector3.Lerp(startPos, mid, t); Vector3 p2 = Vector3.Lerp(mid, savedPosition, t); transform.position = Vector3.Lerp(p1, p2, t); transform.rotation = Quaternion.Slerp(startRot, savedRotation, t); yield return null; } transform.position = savedPosition; transform.rotation = savedRotation; onArrived?.Invoke(); } public void FlyTo(Transform target, Action onArrived = null, Vector3? customOffset = null, Vector3? customRotation = null) { StopAllCoroutines(); isFlying = false; StartCoroutine(FlyCoroutine(target, onArrived, customOffset, customRotation)); } IEnumerator FlyCoroutine(Transform target, Action onArrived, Vector3? customOffset = null, Vector3? customRotation = null) { isFlying = true; Vector3 startPos = transform.position; Quaternion startRot = transform.rotation; float planetRadius = target.lossyScale.x * 0.5f; float scale = planetRadius / 6.371f; Vector3 offset = customOffset.HasValue ? customOffset.Value : finalOffset * scale; Vector3 targetPos = target.position + offset; Quaternion targetRot = customRotation.HasValue ? Quaternion.Euler(customRotation.Value) : Quaternion.Euler(finalRotation); Vector3 mid = Vector3.Lerp(startPos, targetPos, 0.5f); mid += Vector3.up * Vector3.Distance(startPos, targetPos) * 0.3f; mid += Vector3.right * Vector3.Distance(startPos, targetPos) * 0.2f; float elapsed = 0f; while (elapsed < flightDuration) { elapsed += Time.deltaTime; float t = flightCurve.Evaluate(elapsed / flightDuration); Vector3 p1 = Vector3.Lerp(startPos, mid, t); Vector3 p2 = Vector3.Lerp(mid, targetPos, t); transform.position = Vector3.Lerp(p1, p2, t); transform.rotation = Quaternion.Slerp(startRot, targetRot, t); yield return null; } transform.position = targetPos; transform.rotation = targetRot; isFlying = false; onArrived?.Invoke(); } public void FlyToLayer(Transform layer, Action onArrived = null, float cameraMultiplier = 1f) { StopAllCoroutines(); isFlying = false; StartCoroutine(FlyToLayerCoroutine(layer, onArrived, cameraMultiplier)); } IEnumerator FlyToLayerCoroutine(Transform layer, Action onArrived, float cameraMultiplier = 1f) { isFlying = true; Vector3 startPos = transform.position; Quaternion startRot = transform.rotation; float layerRadius = layer.lossyScale.x * 0.5f; Vector3 targetPos = layer.position + new Vector3(layerRadius * 1.1f * cameraMultiplier, layerRadius * 0.3f, -layerRadius * 0.7f * cameraMultiplier); Quaternion targetRot = Quaternion.LookRotation(layer.position - targetPos); float elapsed = 0f; while (elapsed < flightDuration) { elapsed += Time.deltaTime; float t = flightCurve.Evaluate(elapsed / flightDuration); transform.position = Vector3.Lerp(startPos, targetPos, t); transform.rotation = Quaternion.Slerp(startRot, targetRot, t); yield return null; } transform.position = targetPos; transform.rotation = targetRot; isFlying = false; onArrived?.Invoke(); } }