I'm currently in the process of making a 3d "semi" top down game, the camera comes in at a very high angle near 90 to show off the 3d models. I have a main character which can move in 4 axis (up, down, left right) using the arrow keys. I'm trying to create a smooth rotation between each of the axis so that when you press right when the character faces up, his rotation just doesn't jump.

Rotations seem to be weird and I don't quite understand why MathHelper.ConvertToDegrees or Radians doesn't quite give me what I want. When I try to rotate the model, I am translating it back to the origin, rotating then translating back for my order of matrices.

Although what I've found is that for rotation in the Z-axis, 0f seems to be down, 1.6f seems to be right, 3.2f seems to be up and 4.8f seems to be left. So to translate smoothly what I do is say I'm facing up (3.2f) and I want to face, right: Rotation.Z > 1.6 so, while it's greater keep subtracting 0.08f until we reach 1.6 or lower. This works well.

BUT my problem lies in since down is 0 and left is 4.8, when you're facing left and want to face down, you rotate clockwise all the way back to down instead of the logical counter-clockwise. This only happens in left to down or vice versa.

I've thought long and hard about this, down can also be expressed by 5.4f I assume but that doesn't really solve my problem. The approach for going down looks like this:

    else if (currentKeyState.IsKeyDown(Keys.Down))
        //Rotate character to face this direction
        if (rotation.Z != 0)
            if (rotation.Z < 0)
                rotation.Z += 0.08f;
            else if((rotation.Z > 0))
                rotation.Z -= 0.08f;

Since for the left rotation, the rotation.Z value will be 4.8, then by this logic it'll going counter-clockwise. It's probably a simple solution but it has me stumped and one of my biggest problems is not moving on until a problem is fixed even if the game still works.

I've attached a picture of the axis just in case my post is nonsensical:

Axis Rotation

Look forward to any potential solutions.


Looks like you're working in radians, so...

  • up = +/- pi
  • left = -pi/2 = 3pi/2
  • right = pi/2 = -3pi/2
  • down = 0 = +/-2pi

(modulo 2pi)

To get the smallest difference between two input angles, you can use something like...

(disclaimer - this is back-of-napkin, so check it in case I flipped a sign that didn't show up in my pencil test cases)

// Returns the shortest angle from start to end
float AngularDelta(float startAngle, float endAngle)
  float delta = endAngle - startAngle;
  delta = ((((delta + pi) % 2pi) + 2pi) % 2pi) - pi

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.