- Home /

# How to Display Degrees Per Second of each Rotation Axis or 'Local' Angular Velocity

I have a space based lunar module game and I want to display the rotation rate of each axis in the HUD.

I'm not very good with vector math and I tried using the rigidbody.angular velocity but that is aligned with the world axis I quickly found out.

So I tried using the localEulerAngles and testing the difference between them every second.

Like this:

`void FixedUpdate() { if (Time.time >= nextSample) { pitchDiff = Mathf.Abs(Lunar.transform.localEulerAngles.x - lastPitchAngle); yawDiff = Mathf.Abs(Lunar.transform.localEulerAngles.y - lastYawAngle); rollDiff = Mathf.Abs(Lunar.transform.localEulerAngles.z - lastRollAngle);`

` `

```
lastPitchAngle = Lunar.transform.localEulerAngles.x;
lastYawAngle = Lunar.transform.localEulerAngles.y;
lastRollAngle = Lunar.transform.localEulerAngles.z;
nextSample = Time.time + sampleRate;
}
```

`} `

This 'sort of' works but I get bad results when the angle passes to and from 360 to 1 within a second.

I also noticed that it gets less accurate the faster the object spins.

This does seem like a rather crappy approach or I just need to find a better way to derive the angle difference every second.

I essentially want they 'local' angular velocity of each axis.

**Answer** by hellcats
·
May 03, 2011 at 04:37 AM

Try using DeltaAngle. This gives you the minimum difference between two angles

```
pitchDiff = Mathf.DeltaAngle(Lunar.transform.localEulerAngles.x, lastPitchAngle);
```

**Answer** by sh0v0r
·
May 03, 2011 at 05:33 AM

I ended up using the Angle class on the Unify Wiki which has a Difference function.

`void FixedUpdate() { // This code relys on the Angle class which is a Boo script in the standard assets/scripts folder Angle cx = new Angle(Lunar.transform.localEulerAngles.x, AngleMode.Degree); Angle cy = new Angle(Lunar.transform.localEulerAngles.y, AngleMode.Degree); Angle cz = new Angle(Lunar.transform.localEulerAngles.z, AngleMode.Degree);`

` `

```
if (Time.time >= nextSample)
{
Angle lx = new Angle(lastPitchAngle, AngleMode.Degree); // Pitch
pitchRate = (float)(cx.Difference(lx)).Deg;
Angle ly = new Angle(lastYawAngle, AngleMode.Degree); // Yaw
yawRate = (float)(cy.Difference(ly)).Deg;
Angle lz = new Angle(lastRollAngle, AngleMode.Degree); //Roll
rollRate = (float)(cz.Difference(lz)).Deg;
// update last angle values for next sample
lastPitchAngle = Lunar.transform.localEulerAngles.x;
lastYawAngle = Lunar.transform.localEulerAngles.y;
lastRollAngle = Lunar.transform.localEulerAngles.z;
nextSample = Time.time + sampleRate;
}
```

`} `

I need to improve this so the values are updated every frame ins$$anonymous$$d of every second. That should just require some time division of the difference.

**Answer** by sh0v0r
·
May 03, 2011 at 12:40 PM

So here's the current 'realtime' solution, I ended up making my own Angle Difference function and got rid of the Angle class as it was written in Boo and was introducing some weird floating point error.

`float AngleDifference(float angA, float angB) { float diff = Mathf.Abs(angA - angB);`

` `

```
if (diff > 180) diff = 360 - diff;
return diff;
```

}

void FixedUpdate() // used to calculate roll rates and add rotation stabilisation when rotation rate is very low. { float frameDivider = 1 / Time.deltaTime;

```
pitchRate = AngleDifference(Lunar.transform.localEulerAngles.x, lastPitchAngle) * frameDivider;
yawRate = AngleDifference(Lunar.transform.localEulerAngles.y, lastYawAngle) * frameDivider;
rollRate = AngleDifference(Lunar.transform.localEulerAngles.z, lastRollAngle) * frameDivider;
// update last angle values for next sample
lastPitchAngle = Lunar.transform.localEulerAngles.x;
lastYawAngle = Lunar.transform.localEulerAngles.y;
lastRollAngle = Lunar.transform.localEulerAngles.z;
```

`} `

There is a problem still though, Yaw and Roll work perfectly when rotating on a single axis but if I rotate only around the X axis (Pitch) as the angle approaches 90 degrees forward or backward, Yaw and Roll start to show a change in their value, this is because the Euler angles are also World Axis aligned. I tested this by rolling 90 degrees to the side then applying a pitch rotation which caused the Yaw value to change.

So it looks like I am going to have to use some sort of more complex vector derived solution...

**Answer** by Klaus-Eiperle
·
May 21, 2014 at 11:34 AM

Hi,

just found your question. Maybe my reply helps others.

```
Transform _transform;
Rigidbody _rigidbody;
float degreePerSecondY;
Vector3 cachedAngularVelocity;
void Awake() {
_transform = transform; // Transform into cache
_rigidbody = rigidbody; // Rigidbody into cache
}
void FixedUpdate() {
cachedAngularVelocity = _transform.InverseTransformDirection(_rigidbody.angularVelocity);
degreePerSecondY = cachedAngularVelocity.y/Time.fixedDeltaTime;
}
```

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.