- Home /
Why is this rotation not performed as expected?
Situation:
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.
When you say the rotation is complete nonsense, is the actual orientation of the object different between the two approaches? Or are the numbers showing up in the inspector just different?
The Rotation is different between two approaches, simply because somehow it does not rotate the object around z-axis.
Answer by Bunny83 · Sep 30, 2021 at 08:45 AM
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.
Thanks for the detailled response. I actually do use lookRotation now, but anyways I want to know why my described approach does not work. To answer your question about my goal: Imagin a sphere with its position at the world origin. (lets name it earth).
Now I have a coordinate system which is always perpendicular to the earth surface (lets call it perpendicularPlane). The camera is in another coordinate system, which hast the same orientation as the perpendicularPlane. Within the perpendicularPlane-coordinate-system , I have a lot of objects, which should always have the same orientation as the camera but with the constraint that every roll-angle of the cam (means z-rotation) needs to be reverted (that means, every object´s x-axis is perpendicular to the perpendicularPlane).
So what I was thinking , if I first set the object´s rotation equal to the one of the camera and afterwards rotate them back around their forward vector, I should be able to revert the unwanted rotation.
This actually works, but only with Approach1, where I set the z-rotation in inspector to zero, but with Approach2 this does not work. And I would really like to know, why this does not work because I think this knowledge is really important for further developement with unity.