using System.Collections; using System.Collections.Generic; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; using UnityEngine; public class RocketCameraController : MonoBehaviour { [Header("Камера")] [SerializeField] private Camera mainCamera; [SerializeField] private Transform rocketRoot; [SerializeField] private float baseFOV = 60f; private Vector3 _cameraStartPos; private Quaternion _cameraStartRot; private Vector3 _rocketStartPos; private Vector3 _camVelocity = Vector3.zero; private bool _isActive; private RocketFlightCore _core; private float _flightTimer; private float _swayTime; private float _currentShake; private float _targetFOV; public void Initialize(RocketFlightCore core) { _core = core; _cameraStartPos = mainCamera.transform.position; _cameraStartRot = mainCamera.transform.rotation; _rocketStartPos = rocketRoot != null ? rocketRoot.position : Vector3.zero; baseFOV = mainCamera.fieldOfView; _targetFOV = baseFOV; } public void StartFlight() { _isActive = true; _flightTimer = 0f; _swayTime = 0f; _camVelocity = Vector3.zero; _currentShake = 0f; } public void StopFlight() { _isActive = false; } public void ResetCamera() { _isActive = false; _flightTimer = 0f; _camVelocity = Vector3.zero; _currentShake = 0f; mainCamera.transform.position = _cameraStartPos; mainCamera.transform.rotation = _cameraStartRot; mainCamera.fieldOfView = baseFOV; } public void TriggerSonicBoom() { StartCoroutine(SonicBoomShake()); } public void SwitchToSpaceDrift() { } public void StartIgnitionShake(float shakeMultiplier) { StartCoroutine(IgnitionShake(shakeMultiplier)); } private void Update() { if (!_isActive || _core == null || mainCamera == null) return; _flightTimer += Time.deltaTime; _swayTime += Time.deltaTime; UpdateCameraFollow(); UpdateFOV(); UpdateCameraRotation(); } private void UpdateCameraFollow() { float rocketVisualY = rocketRoot.position.y - _rocketStartPos.y; float speedNorm = _core.GetSpeedNormalized(); float spaceProgress = _core.GetSpaceProgress(); float swayX = Mathf.Sin(_swayTime * 13.7f) * speedNorm * 0.06f; float swayY = Mathf.Sin(_swayTime * 9.3f) * speedNorm * 0.03f; float smoothTime = _core.FuelCutoff ? 0.4f : Mathf.Lerp(0.04f, 0.12f, spaceProgress); Vector3 target = _cameraStartPos + Vector3.up * rocketVisualY + new Vector3(swayX, swayY, 0f); mainCamera.transform.position = Vector3.SmoothDamp( mainCamera.transform.position, target, ref _camVelocity, smoothTime); if (_currentShake > 0f) { _currentShake = Mathf.Lerp(_currentShake, 0f, Time.deltaTime * 3f); mainCamera.transform.position += new Vector3( Random.Range(-_currentShake, _currentShake), Random.Range(-_currentShake * 0.5f, _currentShake * 0.5f), 0f); } } private void UpdateFOV() { float speedNorm = _core.GetSpeedNormalized(); float spaceProgress = _core.GetSpaceProgress(); if (_core.FuelCutoff) { _targetFOV = Mathf.Lerp(_targetFOV, baseFOV, Time.deltaTime * 1.5f); } else if (spaceProgress > 0.1f) { _targetFOV = Mathf.Lerp(baseFOV + speedNorm * 15f, baseFOV + 22f, Mathf.Clamp01(spaceProgress * 2f)); } else { _targetFOV = baseFOV + speedNorm * 20f; } mainCamera.fieldOfView = Mathf.Lerp(mainCamera.fieldOfView, _targetFOV, Time.deltaTime * 5f); } private void UpdateCameraRotation() { float speedNorm = _core.GetSpeedNormalized(); float spaceProgress = _core.GetSpaceProgress(); float roll = Mathf.Sin(_swayTime * 5f) * speedNorm * 0.6f; float tiltForward = spaceProgress > 0.3f ? Mathf.Lerp(0f, 4f, (spaceProgress - 0.3f) / 0.7f) : 0f; mainCamera.transform.rotation = Quaternion.Slerp( mainCamera.transform.rotation, _cameraStartRot * Quaternion.Euler(tiltForward, 0f, roll), Time.deltaTime * 2f); } private IEnumerator IgnitionShake(float shakeMultiplier) { float elapsed = 0f; float duration = 2.0f; while (elapsed < duration) { elapsed += Time.deltaTime; float progress = elapsed / duration; float power = progress < 0.15f ? Mathf.Lerp(0f, 0.5f * shakeMultiplier, progress / 0.15f) : Mathf.Lerp(0.5f * shakeMultiplier, 0.02f * shakeMultiplier, (progress - 0.15f) / 0.85f); _currentShake = power; yield return null; } _currentShake = 0f; } private IEnumerator SonicBoomShake() { float elapsed = 0f; float duration = 0.6f; while (elapsed < duration) { elapsed += Time.deltaTime; _currentShake = Mathf.Lerp(0.4f, 0f, elapsed / duration); yield return null; } _currentShake = 0f; } }