using System.Collections; using System.Collections.Generic; using UnityEngine; public class RocketFlightCore : MonoBehaviour { public enum FlightPhase { Idle, Ignition, LaunchPad, LowerAtmosphere, UpperAtmosphere, KarmanLine, Space, DeepSpace, Exploded, Landed } public FlightPhase Phase { get; private set; } = FlightPhase.Idle; public float CurrentHeight { get; private set; } public float Velocity { get; private set; } public float MaxHeightReached { get; private set; } public float AnimTime { get; private set; } public bool FuelCutoff { get; private set; } public bool RocketEscaped { get; private set; } public bool IsActive { get; private set; } public float TotalFuel { get; private set; } public float RemainingFuel { get; private set; } private float _gravity; private float _atmDensity; private float _materialDrag; private float _thrust; private float _animSpeed; private float _fuelBurnRate; private bool _willExplode; private float _explodeDelay; private float _explodeTimer; private float _fuelCutoffTime; private float _escapeVelocity; public void Initialize() { } public void StartFlight(float fuelAmount, float gravity, float atmDensity, float materialDrag, bool willExplode, float explodeDelay) { _gravity = gravity; _atmDensity = atmDensity; _materialDrag = materialDrag; _willExplode = willExplode; _explodeDelay = explodeDelay; _thrust = Mathf.Max(10f, 200f - atmDensity * 1.5f - materialDrag * 30f); _fuelBurnRate = 1f; TotalFuel = fuelAmount; RemainingFuel = fuelAmount; _escapeVelocity = Mathf.Sqrt(2f * gravity * 6371000f) * 0.0001f; float simFuelDuration = fuelAmount / _fuelBurnRate; _animSpeed = simFuelDuration / 18f; CurrentHeight = 0f; Velocity = 0f; MaxHeightReached = 0f; AnimTime = 0f; FuelCutoff = false; RocketEscaped = false; IsActive = true; _explodeTimer = 0f; _fuelCutoffTime = 0f; Phase = FlightPhase.Ignition; } public void ResetFlight() { CurrentHeight = 0f; Velocity = 0f; MaxHeightReached = 0f; AnimTime = 0f; FuelCutoff = false; RocketEscaped = false; IsActive = false; RemainingFuel = 0f; Phase = FlightPhase.Idle; } public bool UpdateFlight(float deltaTime, out bool shouldExplode, out bool flightFinished) { shouldExplode = false; flightFinished = false; if (!IsActive) return false; AnimTime += deltaTime; float dt = deltaTime * _animSpeed; if (_willExplode) { _explodeTimer += deltaTime; if (_explodeTimer >= _explodeDelay) { shouldExplode = true; Phase = FlightPhase.Exploded; IsActive = false; return true; } } bool hasFuel = RemainingFuel > 0f; float currentThrust = 0f; if (hasFuel && !FuelCutoff) { currentThrust = _thrust; RemainingFuel = Mathf.Max(0f, RemainingFuel - _fuelBurnRate * dt); if (RemainingFuel <= 0f) { FuelCutoff = true; _fuelCutoffTime = AnimTime; } } float atmFactor = Mathf.Exp(-CurrentHeight * 0.00001f); float drag = _atmDensity * atmFactor * Velocity * Velocity * _materialDrag * 0.0001f; drag = Mathf.Sign(Velocity) * drag; Velocity += (currentThrust - _gravity - drag) * dt; CurrentHeight = Mathf.Max(0f, CurrentHeight + Velocity * dt); if (CurrentHeight > MaxHeightReached) MaxHeightReached = CurrentHeight; if (FuelCutoff && Velocity > _escapeVelocity * 0.5f) RocketEscaped = true; UpdatePhase(); if (AnimTime >= 25f || (FuelCutoff && CurrentHeight <= 0f && Velocity < 0f)) { if (FuelCutoff && CurrentHeight <= 0f && Velocity < 0f) { shouldExplode = true; Phase = FlightPhase.Exploded; } else { flightFinished = true; } IsActive = false; return true; } return false; } private void UpdatePhase() { if (AnimTime < 0.5f) Phase = FlightPhase.Ignition; else if (CurrentHeight < 1000f) Phase = FlightPhase.LaunchPad; else if (CurrentHeight < 30000f) Phase = FlightPhase.LowerAtmosphere; else if (CurrentHeight < 80000f) Phase = FlightPhase.UpperAtmosphere; else if (CurrentHeight < 100000f) Phase = FlightPhase.KarmanLine; else if (CurrentHeight < 400000f) Phase = FlightPhase.Space; else Phase = FlightPhase.DeepSpace; } public float GetAtmosphereProgress() { return Mathf.Clamp01(CurrentHeight / 100000f); } public float GetSpaceProgress() { return Mathf.Clamp01((CurrentHeight - 100000f) / 300000f); } public float GetSpeedNormalized() { return Mathf.Clamp01(Mathf.Abs(Velocity) / 150f); } public float GetFuelProgress() { return TotalFuel > 0f ? 1f - (RemainingFuel / TotalFuel) : 1f; } public float GetFuelCutoffTime() { return FuelCutoff ? AnimTime - _fuelCutoffTime : 0f; } }