WokerHead
WokerHead

Reputation: 967

Unity: GameObject bug in rotation axis

bug pic

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

Answers (1)

derHugo
derHugo

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

enter image description here

Or to demonstrate it a bit better lets see what happens if we rotate it the way you actually want it to rotate:

enter image description here

as you can see as soon as one axis already is rotated, changing another axis now changes all three rotation values.


Solution

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:

enter image description here

Upvotes: 2

Related Questions