- Home /

# How Do I accurately rotate a player 180 degrees about the Z axis?

So I am working on a gravity altering game that has forced me to better understand how angles work, although I am still struggling. In my game, I want to give the player the ability to flip gravity on demand. (Gravity is manually coded in, it is just a force being constantly applied to vector3.down). However, my issue isn't with gravity, it is with accurately rotating the player 180 degrees. I also have to keep in mind that I plan on the player being able to walk on walls, meaning their rotation may not be strictly 0, 0, 0 or 0, 0, 180 (My current rotation function rotates the player along the Z axis). Basically, if the player was in a cube, the player could be standing on any surface within the cube. But not any slanted surfaces: all surfaces the player walks on are in iterations of 90 degrees. I have code currently to rotate the player, but it does not work accurately. Here is the code:

```
void Update()
{
if (Input.GetButtonDown("Flip"))
{
StartCoroutine(Rotate(rb.rotation * Quaternion.Euler(0, 0, 180)));
}
}
IEnumerator Rotate(Quaternion target)
{
yield return null;
while (Vector3.Angle(rb.rotation.eulerAngles.normalized, target.eulerAngles.normalized) != 0f)
{
rb.MoveRotation(Quaternion.Slerp(rb.rotation, target, .5f));
yield return null;
}
}
```

So when I call Rotate, I pass in the current rotation already rotated 180 degrees around the Z axis, I just have to get to that point. Then I use the IEnumerator to continue to rotate until the angle between the current rotation and our target rotation is zero (Supposedly). Each time it isn't, use MoveRotation and Slerp to get closer, (this way the movement is more smooth). And it "almost" works. I suspect that Vector3.Angle is not totally accurate, because it always stops rotating barely before its target, with a few decimal points off. I tried adding normalized to the vectors being passed in, and I tried using Quaternion.Angle as well, but nothing seemed to fix the issue. I get the feeling that I should be approaching the problem in a completely different manner, but am not sure. Any help is much appreciated.

**Answer** by JDelekto
·
Apr 27 at 10:20 AM

Your problem could very well be the result of floating point calculations which, BTW, can vary by several decimal places in minuscule amounts. You'll probably never really 0.0f *exactly*, which is what your while loop is checking.

Consider a couple of approaches: a) if you know which direction (positive or negative) you are approaching, you can use = instead of != in your while statement; or b) you can multiply your float angle value by some tolerance level (like 1000 if you only care about 3 decimal places, for example), truncate the floating point portion and convert to an integer, then compare to zero.

There may be several other approaches, but I think might help you in the short term, because I think in your case, your while() loop is not finding the exact comparison to 0f.

I appreciate the help, but I actually solved the issue by back tracking and doing it entirely different. To start off, through some testing, I found that for what I am doing, using either of the .Angle functions wouldn't really work, not only because they aren't totally accurate when it comes to decimal points, but also because of the way it is calculated (0, 0, 0 and 0, 0, 180 would return a 0 difference in angle). So instead of checking if I am at my angle target, instead I just keep track of *the amount I have rotated.* With this new method, I also needed a new way of rotating, a function that rotates towards an angle instead of rotating the current angle by a certain amount. After finding out that Quaternion.RotateTowards exist, I came up with this:

```
public float speed; //Speed of rotation at the start
public float minSpeed; //Speed that rotation will gradually lerp to
// Start is called before the first frame update
void Start()
{
StartCoroutine(Rotate());
}
// Update is called once per frame
IEnumerator Rotate()
{
Quaternion target = transform.rotation * Quaternion.Euler(0, 0, 180); //store the target angle we are trying to reach
float amountRotated = 0; //keep track of the amount we have rotated
while(amountRotated <= 180)
{
transform.rotation = Quaternion.RotateTowards(transform.rotation, target, speed);
amountRotated += speed; //the 3rd parameter is the degrees change, so we can keep track of the amount of rotation by adding it each time
speed = Mathf.Lerp(speed, minSpeed, .3f); //slowly reduce the speed, so the rotation has a more natural feel, slowing it down towards the end
yield return null;
}
}
```

And it works just as intended. Thank you for your input though!

### 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.