Initial commit
This commit is contained in:
192
Assets/Scripts/MainEngine.cs
Normal file
192
Assets/Scripts/MainEngine.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class MainEngine : MonoBehaviour
|
||||
{
|
||||
[Header("Fuel Source")]
|
||||
public FuelTank fuelTank; // Reference to the fuel tank supplying this engine
|
||||
|
||||
[Header("Engine Settings")]
|
||||
public float maxThrust = 1000f; // kN
|
||||
public float Isp = 300f; // seconds
|
||||
public float throttleRampTime = 2f; // seconds to reach full throttle
|
||||
public float minStartupFlow = 0.05f; // minimum fraction of max flow to maintain ignition
|
||||
public float g = 9.81f; // gravitational acceleration (m/s^2) (to be replaced)
|
||||
public AnimationCurve throttleCurve = AnimationCurve.Linear(0, 0, 1, 1);
|
||||
|
||||
[Header("Efficiency Settings")]
|
||||
[Range(0f, 1f)] public float engineEfficiency = 1f; // e.g., reduce if engine is hot or damaged
|
||||
|
||||
[Header("Engine Status")]
|
||||
public bool engineOnline = false; // true if engine is running
|
||||
public bool engineIgnited = false; // true if ignition completed
|
||||
public bool restartable = true; // if false, engine cannot restart once shut down
|
||||
public float throttleInput = 0f; // 0-1 input from pilot
|
||||
public float thrust = 0f; // kN
|
||||
public float fuelFlowRate = 0f; // kg/s
|
||||
|
||||
private float effectiveThrottle = 0f; // ramped throttle for smooth startup/shutdown
|
||||
private float startupTimer = 0f;
|
||||
private bool everStarted = false; // tracks if engine has ever been started
|
||||
private float postIgnitionTimer = 0f; // timer for post-ignition grace period
|
||||
private const float postIgnitionGrace = 0.5f; // seconds to allow ramp-up after ignition
|
||||
|
||||
void Update()
|
||||
{
|
||||
HandleEngineState();
|
||||
UpdateThrottle();
|
||||
// Only calculate thrust and fuel flow if engine is ignited
|
||||
if (engineOnline && engineIgnited)
|
||||
{
|
||||
// Update post-ignition timer
|
||||
if (postIgnitionTimer < postIgnitionGrace)
|
||||
postIgnitionTimer += Time.deltaTime;
|
||||
CalculateThrustAndFuelFlow();
|
||||
}
|
||||
else
|
||||
{
|
||||
thrust = 0f;
|
||||
fuelFlowRate = 0f;
|
||||
postIgnitionTimer = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles startup, shutdown, and engine cutout.
|
||||
/// </summary>
|
||||
private void HandleEngineState()
|
||||
{
|
||||
// Check if engine is offline and restartable conditions
|
||||
|
||||
if (!engineOnline)
|
||||
{
|
||||
effectiveThrottle = Mathf.MoveTowards(effectiveThrottle, 0f, Time.deltaTime / throttleRampTime);
|
||||
thrust = 0f;
|
||||
fuelFlowRate = 0f;
|
||||
|
||||
// Mark engine as having been started
|
||||
if (engineIgnited) everStarted = true;
|
||||
|
||||
if (engineIgnited)
|
||||
Debug.Log("[MainEngine] Engine shutdown: engineOnline set to false.");
|
||||
engineIgnited = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent restart if engine is not restartable and was previously started
|
||||
if (!restartable && everStarted)
|
||||
{
|
||||
Debug.Log("[MainEngine] Engine shutdown: not restartable and already started.");
|
||||
engineOnline = false;
|
||||
effectiveThrottle = 0f;
|
||||
thrust = 0f;
|
||||
fuelFlowRate = 0f;
|
||||
engineIgnited = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Engine is commanded online
|
||||
if (!engineIgnited)
|
||||
{
|
||||
// Startup delay / ignition sequence
|
||||
startupTimer += Time.deltaTime;
|
||||
if (startupTimer >= throttleRampTime)
|
||||
{
|
||||
engineIgnited = true;
|
||||
startupTimer = 0f;
|
||||
postIgnitionTimer = 0f; // reset grace period timer
|
||||
Debug.Log("[MainEngine] Engine ignition complete.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Slowly ramp effective throttle during startup
|
||||
effectiveThrottle = Mathf.Lerp(0f, throttleInput, startupTimer / throttleRampTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Smooths throttle input over time (fuel ramping)
|
||||
/// </summary>
|
||||
private void UpdateThrottle()
|
||||
{
|
||||
if (!engineOnline || !engineIgnited)
|
||||
return;
|
||||
|
||||
// Smooth throttle changes to avoid instant jumps
|
||||
effectiveThrottle = Mathf.MoveTowards(effectiveThrottle, throttleInput, Time.deltaTime / throttleRampTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates thrust and fuel flow based on current throttle and efficiency
|
||||
/// </summary>
|
||||
private void CalculateThrustAndFuelFlow()
|
||||
{
|
||||
// Base thrust from throttle curve and max thrust
|
||||
thrust = throttleCurve.Evaluate(effectiveThrottle) * maxThrust * engineEfficiency;
|
||||
|
||||
// Fuel flow based on thrust and Isp
|
||||
fuelFlowRate = thrust / (Isp * g);
|
||||
|
||||
// Request fuel from the tank if assigned
|
||||
if (fuelTank != null)
|
||||
{
|
||||
float fuelRequested = fuelFlowRate * Time.deltaTime;
|
||||
float fuelProvided = fuelTank.RequestFuel(fuelRequested);
|
||||
if (fuelProvided < fuelRequested)
|
||||
{
|
||||
Debug.Log($"[MainEngine] Engine flameout: insufficient fuel (requested {fuelRequested:F3}, got {fuelProvided:F3}).");
|
||||
engineIgnited = false;
|
||||
effectiveThrottle = 0f;
|
||||
thrust = 0f;
|
||||
fuelFlowRate = 0f;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Only check for flameout if engine is fully ignited and grace period has passed
|
||||
float nominalFlow = maxThrust / (Isp * g);
|
||||
if (engineIgnited && postIgnitionTimer >= postIgnitionGrace && (fuelFlowRate / nominalFlow) < minStartupFlow)
|
||||
{
|
||||
Debug.Log($"[MainEngine] Engine flameout: fuel flow below minimum ({fuelFlowRate / nominalFlow:F3} < {minStartupFlow}).");
|
||||
engineIgnited = false; // engine flameout
|
||||
effectiveThrottle = 0f;
|
||||
thrust = 0f;
|
||||
fuelFlowRate = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call to turn the engine on
|
||||
/// </summary>
|
||||
public void StartEngine()
|
||||
{
|
||||
if (!engineOnline)
|
||||
{
|
||||
// Prevent starting if not restartable and already started
|
||||
if (!restartable && everStarted)
|
||||
{
|
||||
Debug.Log("[MainEngine] StartEngine() called but engine is not restartable and has already started.");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("[MainEngine] Engine start command received.");
|
||||
engineOnline = true;
|
||||
startupTimer = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call to turn the engine off
|
||||
/// </summary>
|
||||
public void ShutdownEngine()
|
||||
{
|
||||
Debug.Log("[MainEngine] Engine shutdown command received.");
|
||||
engineOnline = false;
|
||||
engineIgnited = false;
|
||||
}
|
||||
|
||||
public void SetThrottle(float value)
|
||||
{
|
||||
throttleInput = Mathf.Clamp01(value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user