I’m making a flight-sim-esque game, and I’ve created a HUD-style attitude indicator. So far I’ve implemented an Angle-of-Attack indicator and a bank indicator and I’m trying to add a pitch indicator now.
I’m calculating bank using a bit of a trick. I have a helper transform, and I set its forward vector equal to the vehicle forward. Exploiting the fact that the up vector always tries to orient to world up, I can calculate the vehicle’s bank by comparing the helper’s up vector to the vehicle’s up vector:
AttitudeHelper.forward = transform.forward;
if (Vector3.Dot(transform.up, AttitudeHelper.right) > 0)
{myAttitudeIndicator.bank = -Vector3.Angle(AttitudeHelper.up, transform.up);}
else
{myAttitudeIndicator.bank = Vector3.Angle(AttitudeHelper.up, transform.up);}
So far so good - the bank indicator is reliable, so I thought I’d try the same trick by setting the helper’s right vector to the vehicle’s right vector, then comparing their up vectors:
AttitudeHelper.right = transform.right;
if (Vector3.Dot(transform.up, AttitudeHelper.forward) > 0)
{myAttitudeIndicator.pitch = -Vector3.Angle(AttitudeHelper.up, transform.up);}
else
{myAttitudeIndicator.pitch = Vector3.Angle(AttitudeHelper.up, transform.up);}
This creates a pitch indicator that is only right when the bank is zero. If the wings are banked even a little, I get weird results.
In order to calculate the pitch, I need a vector with the same heading as the vehicle’s, but flat. I can’t think of a way to do this. I haven’t been through the maths, I’ve just exploited a fluke of the way Unity sets rotations to get a correct bank value, but it doesn’t work for pitch, so I have to do some real maths now. Any ideas?
EDIT: I was actually comparing the up vectors - I’ve changed the text to reflect this, although this code has exactly the same problems:
AttitudeHelper.forward = transform.forward;
if (Vector3.Dot(transform.up, AttitudeHelper.right) > 0)
{myAttitudeIndicator.bank = -Vector3.Angle(AttitudeHelper.right, transform.right);}
else
{myAttitudeIndicator.bank = Vector3.Angle(AttitudeHelper.right, transform.right);}
AttitudeHelper.right = transform.right;
if (Vector3.Dot(transform.up, AttitudeHelper.forward) > 0)
{myAttitudeIndicator.pitch = -Vector3.Angle(AttitudeHelper.forward, transform.forward);}
else
{myAttitudeIndicator.pitch = Vector3.Angle(AttitudeHelper.forward, transform.forward);}