我在 unity 2d 中制作了一个非常简单的火箭模拟器,但在所有功能中,我无法让 delta V 工作。我在发射前就预先计算过了,但是当火箭燃料耗尽时,结果却不是这样。
这里是完整的代码:
using UnityEngine;
using UnityEngine.UI;
public class PhysicsScript : MonoBehaviour
{
Vector2 weight;
Vector2 thrustForce;
Rigidbody2D rb;
Vector2 netForce;
Vector2 dragForce;
float fuelConsumption;
float altitude;
bool enginesToggle;
float dragRatio;
bool TurnL;
bool TurnR;
float ThrustPercentage;
bool shiftHeld;
float yVel;
float xVel;
public float fuel;
public float fuelDensity;
public float g;
public float rocketMass;
public float massFlowRate;
public float exhaustVelocity;
public float dragCoefficient;
public float maxAtmosphereAlt;
public float TurningForce;
public Text AltitudeText;
public Slider thrustSlider;
public Text Percentage;
public Text VerticalVel;
public Text HorizontalVel;
public Slider fuelSlider;
public Text FuelPercentage;
public Text BTDisplayer;
public Text WTRat;
public Text WeightD;
public Text ThrustD;
public Text MassD;
public Text DelataVD;
public Image engineOnOff;
public Text tti;
public Text APoapsis;
public Text dragD;
float burnTime;
float W_TRatio;
float secondsBeforeHittingGround;
float apoapsis;
float deltaV;
float finalMass;
void Start()
{
rb = GetComponent<Rigidbody2D>();
fuelSlider.maxValue = fuel;
fuelSlider.value = fuelSlider.maxValue;
}
void Update()
{
yVel = rb.velocity.y;
xVel = rb.velocity.x;
fuelSlider.value = fuel;
FuelPercentage.text = (fuel * 100 / fuelSlider.maxValue).ToString("0") + "%";
VerticalVel.text = "Vertical Velocity: " + yVel.ToString("0") + " m/s";
HorizontalVel.text = "Horizontal Velocity: " + xVel.ToString("0") + " m/s";
if (Input.GetKeyDown(KeyCode.Space))
{
enginesToggle = !enginesToggle;
}
if (Input.GetKey(KeyCode.D))
{
TurnR = true;
}
else
{
TurnR = false;
}
if (Input.GetKey(KeyCode.A))
{
TurnL = true;
}
else
{
TurnL = false;
}
AltitudeText.text = "Altitude: " + altitude.ToString("0") + " m";
float scroll = Input.GetAxis("Mouse ScrollWheel");
shiftHeld = Input.GetKey(KeyCode.LeftShift);
if (shiftHeld && scroll != 0)
{
thrustSlider.value += scroll / 10;
}
else if (scroll != 0)
{
thrustSlider.value += scroll / 3;
}
ThrustPercentage = thrustSlider.value;
ThrustPercentage = Mathf.Clamp(ThrustPercentage, 0, 1);
Percentage.text = "Thrust \n" + (thrustSlider.value * 100).ToString("F1") + "%";
}
void FixedUpdate()
{
rb.mass = rocketMass + fuel * fuelDensity;
if (altitude > maxAtmosphereAlt)
{
dragCoefficient = 0;
}
dragRatio = altitude / maxAtmosphereAlt;
//weight
weight = rb.mass * g * Vector2.down;
//drag
dragForce = dragCoefficient * Mathf.Pow(rb.velocity.magnitude, 2) * -rb.velocity;
//fuel and mass consumptions
fuelConsumption = exhaustVelocity * massFlowRate * ThrustPercentage;
altitude = transform.position.y;
if (fuel > 0 && enginesToggle)
{
//thrust
thrustForce = transform.up * fuelConsumption * exhaustVelocity * ThrustPercentage;
fuel -= fuelConsumption * Time.deltaTime;
engineOnOff.color = Color.green;
apoapsis = 0;
secondsBeforeHittingGround = 0;
}
else
{
thrustForce = Vector2.zero;
engineOnOff.color = Color.red;
apoapsis = Mathf.Pow(yVel, 2) / Mathf.Pow(g, 2);
secondsBeforeHittingGround = apoapsis * 2 / g;
}
//net
netForce = (weight + thrustForce + dragForce) * Time.fixedDeltaTime;
rb.velocity += netForce / rb.mass;
fuel = Mathf.Clamp(fuel, 0, fuel);
dragCoefficient = Mathf.Lerp(dragCoefficient, 0, dragRatio * Time.fixedDeltaTime);
if (TurnR)
{
rb.AddTorque(-TurningForce * rb.mass);
}
if (TurnL)
{
rb.AddTorque(TurningForce * rb.mass);
}
rb.AddTorque(-4 * rb.angularVelocity * rb.mass * Time.fixedDeltaTime);
burnTime = fuel / fuelConsumption;
W_TRatio = (exhaustVelocity * massFlowRate * ThrustPercentage) / weight.magnitude;
BTDisplayer.text = "Burn Time: " + burnTime.ToString("0") + "s";
WTRat.text = "T/W Ratio: " + W_TRatio.ToString("F2") + "x";
WeightD.text = "Weight: " + weight.magnitude.ToString("0") + "N";
ThrustD.text = "Thrust: " + (exhaustVelocity * massFlowRate * ThrustPercentage).ToString("0") + "N";
deltaV = Mathf.Log(rb.mass / rocketMass) * massFlowRate * exhaustVelocity;
MassD.text = rb.mass.ToString("0") + "kg";
DelataVD.text = "work in progress..";
tti.text = "Time to Apoapsis: " + (secondsBeforeHittingGround).ToString("0") + "s";
APoapsis.text = "Distance Apoapsis: " + apoapsis.ToString("0") + "m";
dragD.text = "Drag: " + Mathf.Clamp((100 - (altitude * 100 / maxAtmosphereAlt)), 0, 100).ToString("F1") + "%";
}
}
希望它不那么难读。
我用计算器计算了delta V,当模拟火箭排空时,它的速度甚至没有接近我的预期。我对代码做了很多调整,这使它变得更糟,所以我撤消了它们。
所以,如您所见,我身上有 1000 燃料。燃料密度为0.3,燃料质量为300。火箭也有10kg。总共将是 310 公斤。火箭上没有阻力或重力。排气速度为100。若delta V = Ln(m0/mf)*ve,则deltaV = Ln(310/10)*100, deltaV = Ln(31)100,deltaV = 3.43100,结果 DeltaV = 343 m/s,而事实上,我的最大速度是 1150。 帮忙吗?