185 lines
5.4 KiB
C#
185 lines
5.4 KiB
C#
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;
|
|
}
|
|
}
|