Files
ScienceLab.AtmosphericPressure/Assets/Scripts/CameraController.cs
2026-05-29 18:21:53 +03:00

123 lines
4.7 KiB
C#

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