Boy*_*esz 2 c# air math physics unity-game-engine
我想做一个简单的飞机控制器,看起来一点也不现实。我看了一些飞机物理学的视频。并统一编写一个简单的脚本,但是如果我开始,飞机无法移动,或者如果将阻力更改为零,飞机将无法升起。我试图使用真实数据并从Wiki(F22 Raptor)中获取数据。对于我的游戏对象,我给定了刚体组件的质量= 19670 kg。发动机推力= 2 * 116000.0f牛顿。
private void calculateEnginePower()
{
EnginePower = engineThrust * ThrottleInput;
}
private void calculateForces()
{
angleOfAttack = Vector3.Angle(Vector3.forward, rb.velocity);
angleOfAttack = Mathf.Clamp(angleOfAttack, 0, 90);
coefficient = Mathf.Pow(1225.04f * rb.velocity.magnitude, 2) - 1; //M^2-2 where: M is mach.
if (coefficient > 0.0f)
coefficientLift = (4 * angleOfAttack) / Mathf.Sqrt(coefficient);
lift = 1.2754f * 0.5f * Mathf.Pow(rb.velocity.magnitude, 2) * coefficientLift * 78.04f; // densy1.2754 kg/m3, speed m/s , (F22)Wing area: 840 ft² (78.04 m²)
coefficientDrag = 0.021f;
rb.drag = coefficientDrag * 0.5f * Mathf.Pow(rb.velocity.magnitude,2) * 1.2754f * 78.04f;
rb.AddForce(transform.up * lift);
rb.AddForce(transform.forward * EnginePower);
}
Run Code Online (Sandbox Code Playgroud)
使用以下公式:
用于提升力: 用于提升系数的提升公式: 用于拖动的Cl公式: 拖动公式 ,对于用于拖动系数:我也使用了来自Wiki(0.021f)的数据。
Lec*_*ece 10
因此,您的代码存在许多问题。我在下面概述了它们;
计算力
问题:
angleOfAttack = Vector3.Angle(Vector3.forward, rb.velocity);
Vector3.forward并且rb.velocity都在世界空间中。AoA是机翼的局部弦线与飞机的弦线之间的夹角velocity。Vector3.Angle将返回一个无符号的角度。AoA必须在正向和负向都起作用,否则将无法实现负俯仰和反向飞行。
解决方案: 移至
rb.velocity局部空间并AoA使用三角函数求解。
// *flip sign(s) if necessary*
var localVelocity = transform.InverseTransformDirection(rb.velocity);
var angleOfAttack = Mathf.Atan2(-localVelocity.y, localVelocity.z);
Run Code Online (Sandbox Code Playgroud)
问题:
coefficient = Mathf.Pow(1225.04f * rb.velocity.magnitude, 2) - 1;
4?/sqrt(M^2?1)是M> 1的超声波系数。当速度为零时,该方程将减小sqrt(-1)为一个虚数NaN。马赫表示为M=V/Cwhere V=velocity和C=the speed of sound。您的1225.04f常数必须以Ckm / h为单位,而不是必需的m / s。你也倍增,而不是除以如方程给出。解决方案: 使用提升线理论简化方程式。
var aspectRatio = (wingSpan * wingSpan) / wingArea;
var inducedLift = angleOfAttack * (aspectRatio / (aspectRatio + 2f)) * 2f * Mathf.PI;
var inducedDrag = (inducedLift * inducedLift) / (aspectRatio * Mathf.PI);
Run Code Online (Sandbox Code Playgroud)

资料来源: Aerospaceweb.org
问题:
rb.drag = coefficientDrag * 0.5f * Pow(rb.velocity.mag,2) * 1.2754f * 78.04f;
rb.drag 不需要,因为我们正在手动计算和应用拖动。解决方案: 将
rb.drag属性设置为最小的值。
rb.drag = Mathf.Epsilon; // set in Awake
Run Code Online (Sandbox Code Playgroud)
问题:
rb.AddForce(transform.up * lift);
transform.up不正确的lift。升力作用垂直于velocity而drag行为平行。
解决方案: 通过将归一化矢量与飞机的横向方向相交来计算
lift方向,velocity并drag与相对velocity。
// *flip sign(s) if necessary*
var dragDirection = -rb.velocity.normalized;
var liftDirection = Vector3.Cross(dragDirection, transform.right);
rb.AddForce(liftDirection * lift + dragDirection * drag);
Run Code Online (Sandbox Code Playgroud)
您的提升方程看起来不错,因此将它们放在一起看起来像这样;(未经测试)
public float wingSpan = 13.56f;
public float wingArea = 78.04f;
private float aspectRatio;
private void Awake ()
{
rb.drag = Mathf.Epsilon;
aspectRatio = (wingSpan * wingSpan) / wingArea;
}
private void calculateForces ()
{
// *flip sign(s) if necessary*
var localVelocity = transform.InverseTransformDirection(rb.velocity);
var angleOfAttack = Mathf.Atan2(-localVelocity.y, localVelocity.z);
// ? * 2 * PI * (AR / AR + 2)
var inducedLift = angleOfAttack * (aspectRatio / (aspectRatio + 2f)) * 2f * Mathf.PI;
// CL ^ 2 / (AR * PI)
var inducedDrag = (inducedLift * inducedLift) / (aspectRatio * Mathf.PI);
// V ^ 2 * R * 0.5 * A
var pressure = rb.velocity.sqrMagnitude * 1.2754f * 0.5f * wingArea;
var lift = inducedLift * pressure;
var drag = (0.021f + inducedDrag) * pressure;
// *flip sign(s) if necessary*
var dragDirection = rb.velocity.normalized;
var liftDirection = Vector3.Cross(dragDirection, transform.right);
// Lift + Drag = Total Force
rb.AddForce(liftDirection * lift - dragDirection * drag);
rb.AddForce(transform.forward * EnginePower);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3738 次 |
| 最近记录: |