Rotate odd behaviour

I am using the most basic implementation of rotate for a directional light (well, for a transform really).

While it does what I want, it doesn’t seem to be working properly.

My transform is set to start at 0,0,0 rotation.
I’m using the docs example

        transform.Rotate(Vector3.right * Time.deltaTime);

Not only is it rotating the X axis, but the Y and Z are also increasing at exponential rates.
Now the worst part: once the X axis hits 90 degrees, it pauses for a brief period, and then starts going backwards from 90. The Y and Z get set to 0 and more strange stuff continues. This is really problematic because I want to base some stuff off the rotation of the X axis, and I cannot get passed 90 degrees.

The truly worst part is, everything looks fine in the editor/game preview. The light is in fact rotating 360 degrees continually, but the editor and Debug.Log() tell me it gets to 90 and then starts going backwards. What’s going on?

So, it’s properly rotating, and it’s just the readouts on the inspector that look wrong?

I think this is due to a misunderstanding of the way rotations are stored. The Euler angles that you see in the inspector are not the actual values; it stores a Quaternion (x,y,z, and w, none of which are in degrees or bear any direct relation to the X,Y,Z you see in the inspector), and converts that back to Euler angles to display in the inspector.

Take a different approach; you should basically never count on the Euler angles of a rotation being compared to any particular number. You might use transform.forward and compare that vector (if transform.forward.z is negative, for example, the rotation is probably above 90 degrees). You might track your own local variable to determine how much time has passed, directly set transform.rotation.eulerAngles = new Vector3(yourVariable, 0f, 0f). Probably a few other ways if neither of those fit your needs.

1 Like

I see. Rotation in Unity, in my opinion, is absurd. I can clearly rotate an object around axis X/Y/Z in the inspector. I can clearly read the value from this in a script. Yet I cannot set transform.rotation.x to what I want. I will try the eulerAngles method…

This is not just Unity; Quaternions are a widely accepted standard for any modern 3D engine. They’re faster, the math is more consistent and reliable, and they don’t suffer from gimbal lock.

until you try to work out a euler approach for getting around the problems they solve :stuck_out_tongue:

Regardless, I don’t care what Unity does in the background. If I set the transform.rotation.x to add 1 degree each update, it should just do it - just like I can in the editor.

Allow me to explain why that’s wrong.

When you type in (180, 0, 0) in the Inspector, it’s fairly clear what’s going on. But let’s say you type in 540. It’s the same rotation, and when converted to a quaternion it’ll be identical, yet the inspector still leaves it as 540. With Euler angles, there are an infinite number of numbers that all mean the same rotation (x, x+360, x+720, etc, for all three axes); all of these identical values are converted to the same quaternion. More to the point, it would be equally valid for the quaternion-to-Euler algorithm to turn a given Quaternion into (180,0,0), or (540,0,0), or (900,0,0), or (180,360,360)… it has to pick one.

Similarly, when you use all three Euler numbers, there are other combinations where the same rotation is represented by multiple Euler combos. For example, (90,0,0) is identical to (90,90,90). And, given a particular Quaternion, it would be just as valid for Quat-to-Euler algorithm to spit out either (90,0,0) or (90,90,90) or (90,270,270). Again, when you type these into the inspector, the values stay the same as you typed them. However, when you give it a quaternion in script - which is what you’re doing when you type in transform.Rotate - the inspector values for these would no longer be maintained, because a function that converts a given Quaternion to Euler values can only have one possible output - because it’s an algorithm.

So how does the Inspector maintain the values when you type them in? It cheats. It actually remembers the Euler values you type in (and, I believe, stores them this way in the scene file as well), and as long as the rotation isn’t changed elsewhere, it knows that that particular Quaternion still means those values you typed in. But as soon as it doesn’t have that context of “I actually typed these particular numbers”, it has no way of possibly knowing what values would make sense to you.