- Home /
Get angle from mouse direction?
I have an object that I wish to rotate at the same angle as the mouse movement direction. I have used the following code:
mouseLeftRight = Input.GetAxis ("Mouse X") * 1.5f;
mouseUpDown = Input.GetAxis ("Mouse Y") * 1.5f;
angle = Mathf.Atan2 (mouseUpDown, mouseLeftRight) * Mathf.Rad2Deg;
if (angle<0) angle += 360;
transform.localEulerAngles = new Vector3 (transform.localEulerAngles.x,
transform.localEulerAngles.y,
angle);
Debug.Log shows me that the angle is suitable; If I move the mouse right, angle is 0, up and angle is 90, left and angle is 180, down and angle is 270.
The object I am applying the rotation to sometimes works as expected, although jittery, but most of the time it just spins rapidly on its local Z-axis as if a rotation is being constantly added. When it does this, debug.log tells me that the transform.localEulerAngles.z of the object = 0.
I do not understand why it is doing this. Can anyone help?
Answer by ncallaway · Jan 10, 2014 at 01:25 AM
The reason it is jittery and not as you expect is because Input.GetAxis () returns you the mouse delta for the previous frame. You're using it to set absolute rotation. This can cause a lot of jittery movement.
Consider a mouse movement towards 45° (up and to the right). Let's assume it happens over the course of two frames. One user executes a smooth mouse movement, and each frame the delta mouse movement is (1, 1). Another user executes a slightly jittery mouse movement, and the first frame the delta mouse movement is (2, 0) and the next frame the delta mouse movement is (0, 2).
User 1 does something like this:
User 2 does something like this:
In the code that you've presented, the first user will see what they want (the object rotated nicely to 45°). The second user will probably see something jittery and unsatisfying. The first frame the cylinder will rotate to 0° (because of the (2,0) delta mouse movement). The second frame the cylinder will rotate to 90° (because of the (0, 2) delta mouse movement). For both users, on the third frame (when they've stopped moving the mouse) the cylinder will rotate back to 0°. Unfortunately, when it comes to mouse movement, we are pretty much all user 2.
To get what you want, you need to use mouse deltas to apply rotation deltas, or mouse absolute distance from a reference point to apply absolute rotation. A quick example of the "absolute" solution is below. This solution waits for the user to click the mouse before applying any rotation. When the user first presses the mouse button down, we set the "origin" of the movement at the current mouse location. As the user moves the mouse (keeping the mouse button held down), we compare the mouse position to the origin that we set at the beginning of the drag. We use this "absolute" mouse position to set an absolute rotation value.
public class Rotation : MonoBehaviour {
private Vector3 startPosition;
void Update() {
if (Input.GetMouseButtonDown(0))
{
startPosition = Input.mousePosition;
}
if (Input.GetMouseButton(0))
{
Vector3 mouseDelta = Input.mousePosition - startPosition;
if (mouseDelta.sqrMagnitude < 0.1f)
{
return; // don't do tiny rotations.
}
float angle = Mathf.Atan2 (mouseDelta.y, mouseDelta.x) * Mathf.Rad2Deg;
if (angle<0) angle += 360;
Debug.Log (angle);
transform.localEulerAngles = new Vector3 (transform.localEulerAngles.x,
transform.localEulerAngles.y,
angle);
}
}
}
Thanks very much for your response. The code you supplied doesn't seem to function correctly though. Debug.Log shows that the mouseDelta never exceeds 1 in the x or y direction, and the object still spins rapidly and wrongly on the z-axis. I forgot to mention that I am using a first-person camera. Though it doesn't reset the mouse position anywhere in it's code. Any other ideas? $$anonymous$$any thanks again.
edit1: I have found that my first person camera is causing the problem. If I disable the code for it temporarily, then the code you posted works as expected. Do you know of a way to do this same operation when using a first-person camera? It seems to set mouseDelta to 0,0 rapidly.
Please don't post comments as answers. Post comments by clicking the [add new comment] button, a window then open for you to type in. Answer fields are for answers only, as this is a knowledge base.
Here at Unity Answers, Answer means Solution, not Response.
Read this page : http://answers.unity3d.com/page/newuser.html
Please watch : http://video.unity3d.com/video/7720450/tutorials-using-unity-answers
I have converted this one for you.
What first person camera are you using? Is it the First Person Controller from Standard Assets? Or something else?
I just found the problem. $$anonymous$$y first person controller script had the line
Screen.lockCursor = true;
Disabling that makes your script work perfectly. Thanks very much!
Your answer
![](https://koobas.hobune.stream/wayback/20220613130006im_/https://answers.unity.com/themes/thub/images/avi.jpg)