192 lines
5.5 KiB
C#
192 lines
5.5 KiB
C#
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;
|
|
}
|
|
}
|