Reputation: 967
In the GIF above I am moving the plane with the mouse up and down. Watch how when I rotate the plane on its Z axis the plane still moves up and down even if the plane is side ways now. That is my bug. Why is this happening? What is wrong with my code? I think I am using the global axis and not the gameobjects axis. How do I fix this please.
x += Input.GetAxis("Mouse X") * xMouseSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * yMouseSpeed * 0.02f;
if (Input.GetKey(KeyCode.Q))
{
rotZ += Time.deltaTime * 50f;
}
if (Input.GetKey(KeyCode.E))
{
rotZ -= Time.deltaTime * 50f;
}
Quaternion rotation = Quaternion.Euler(y, x, rotZ);
planeBodyToMove.localRotation = rotation;
Upvotes: 0
Views: 1020
Reputation: 90629
What happens is that the localRotation
is just the rotation in relation to the parent object.
The rotation of the transform relative to the transform rotation of the parent.
Or in other words: The localRotation
is not local to the object itself but rather a rotation in the local space of the parent (or Unity world space if there is no parent). It does not mean that you rotate around your local Y axis necessarily. It applies the rotations in the parent's local space in the order Z
, X
, Y
.. that is why sometimes you actually don't note the difference until you rotate Y
!
As you can see here the same thing happens also without your code by just doing the rotation via the Inspector
Or to demonstrate it a bit better lets see what happens if we rotate it the way you actually want it to rotate:
as you can see as soon as one axis already is rotated, changing another axis now changes all three rotation values.
So how to solve this?
Usually I'm to lazy to do Quaternion
calculations myself → I let the Transform
do this for me ^^
Instead of storing the expected rotation in fields and apply it everytime by converting it into a Quaternion
you can directly use Transform.Rotate
which rotates the object actually using its own local axis:
// Just a question of taste but I would prefer to have
// values that belong together in one single struct instead of multiple fields
public Vector2 mouseSensitivity = Vector3.one;
private void Update()
{
var xDif = Input.GetAxis("Mouse X") * mouseSensitivity.x;
var yDif = - Input.GetAxis("Mouse Y") * mouseSensitivity.y;
var zDif = 0f;
if (Input.GetKey(KeyCode.Q))
{
zDif= Time.deltaTime * 50f;
}
else if (Input.GetKey(KeyCode.E))
{
zDif= -Time.deltaTime * 50f;
}
// Wihout the optional space parameter uses local space by default
planeBodyToMove.Rotate(new Vector3(xDif, yDif, zDif));
}
As you can see now each rotation is actually applied in the plane's local axis:
Upvotes: 2