void FixedUpdate() { /* Determine relative wind. */ Vector3 windDirection = atmosphere.WindVelocityAt(transform.position); relativeVelocity = GetComponent <Rigidbody>().velocity - windDirection; trueAirspeed = relativeVelocity.magnitude; /* Determine angle of attack. (keep in mind that forward direction is the Up/Y axis, not Z) */ Vector3 forward = transform.TransformDirection(Vector3.up); Vector3 right = transform.TransformDirection(Vector3.right); Vector3 up = transform.TransformDirection(Vector3.down); Vector3 horizontalRight = new Vector3(right.x, 0f, right.z); angleOfAttackPitch = Mathx.AngleAroundAxis(forward, relativeVelocity, right); angleOfAttackYaw = Mathx.AngleAroundAxis(right, relativeVelocity, up); // Angle of attack falls off to 0 based on the amount of sideslip (not being aligned to direction of flight) float alphaSideFalloff = Mathx.ClampAngle(angleOfAttackYaw + 90f, -360f, 360f, 180f); alphaSideFalloff = sideFalloffCurve.Evaluate(alphaSideFalloff); float airDensity = atmosphere.AirDensityAt(transform.position); /* Determine lift around pitch axis based on angle of attack, using coefficient lookup. */ cLift = cLiftCurve.Evaluate(angleOfAttackPitch) * alphaSideFalloff; lift = .5f * airDensity * Mathf.Pow(trueAirspeed, 2f) * surfaceArea * cLift * liftMultiplier; // Determine lift vector as perpendicular to the relative airflow liftVector = Vector3.Cross(relativeVelocity, right).normalized *lift; /* Determine profile drag around the pitch axis. */ float cDrag = cDragCurve.Evaluate(angleOfAttackPitch); drag = .5f * airDensity * trueAirspeed * trueAirspeed * surfaceArea * cDrag; dragVector = -relativeVelocity.normalized * drag; /* Add some simple lateral drag to minimize sideslip, convert a portion of it to forward speed like in Wipeout */ sideSlip = Vector3.Project(relativeVelocity, horizontalRight); Vector3 sideSlipNegation = -sideSlip * 25f; sideSlipNegation += forward * sideSlipNegation.magnitude * 0.65f; /* Apply the forces. */ GetComponent <Rigidbody>().AddForceAtPosition(liftVector + dragVector + sideSlipNegation, transform.TransformPoint(centerOfPressure)); }