Why is this rotation not performed as expected?


Assume you have a camera somewhere in worldspace and a GameObject “go1” on the same hierarchy-level as the camera. go1 and the camera are rotated somehow in worldspace. Within go1 you have another nested gameobject go2.

Before any of the following approaches, you call in script:

go2 .transform.rotation = camera.transform.rotation;

After that, two different approaches lead to different results:

Approach1 (in editor):

Now you see the new local rotation within go2´s transform in the inspector. Now, if you change go2´s z-rotation value to 0, everything happens as expected. The go is rotated around z-axis and basically go2´s local z-rotation is reverted

Approach2 (in code):

In contrast, if I calculate the Inspector´s local z-rotation “calcZRot” as described here, and call:

go2.transform.localRotation = Quaternion.AngleAxis(-calcZRot, go2.transform.forward)

Usually I expect the same things will happen as in the Editor-Approach, but it doesn´t! The rotation is complete nonsense and not reverting the local z-Rotation of go2.

Basially, the Rotation of go2 should behave same as:

LookRotation(camera.transform.forward, go1.transform.up);

I Just like to know, why this wrong rotation happens, even if there is a solution for this. It seems like the rotation is simply not beeing performed around z-Axis.

You have the wrong idea of quaternions ^^. A quaternion is always a relative rotation around a single axis. To represent an absolute orientation with a quaternion (which we do with transform.rotation) it has to represent a rotation that brings your coordinate system from the initial orientation to the target rotation. Imagine a simple case where the camera is first looking straight without any rotation. If you rotate the camera 90° to the right it means it’s forward axis will change from (0,0,1) to (1,0,0) since the camera is now facing to the right. However which rotation axis gets you there? Exactly, a rotation around the y axis. That would be the axis you have to specify for AngleAxis.

Most prople make the mistake of still thinking in terms of euler angles. Euler angles are 3 seperate rotations around 3 axis performed one after the other in a particular order. A quaternion represents the combined rotation as one single rotation. The actual rotation axis of the localRotation could be any uninuitive axis since it essentially has to rotate your object within the local space of the parent from the not rotated state to the target rotation with a single rotation axis.

It’s actually an amazing fact that you can rotate toany orientation in space by just a single axis rotation. It’s difficult to tell whats your exact goal and why you need this specific setup. Why don’t you use LookRotation? Keep in mind that LookRotation also works for local rotations as long as the direction vectors you use are in that local space the rotation lives in. That means the parent coordinate space.

This question somehow reminds me of this question we just had about 2 weeks ago. A different case but it also has to do with manipulating the child rotation so it aligns with a worldspace orientation, though with an offset.