Order matters - but

So, the repeated mantra is that order matters when it comes to rotation. Rotating the ship locally using the transform did indicate this.

But entering a single line of code using the Quaternion.Euler seems to order Unity to do what we want without any odd implications. To the mathematical ignoramus (i.e. me!) - all this says to me is that this is a fairly typical way to handle rotation without unexpected consequences - but having read (or tried to read) the wiki article on Quaternions - I’m none the wiser as to why simply sticking a new vector 3 in there isn’t the way to do it. Well, I know it isn’t the way to do it because I thought I’d try it, and got an error!

I swapped;

transform.localRotation = Quaternion.Euler(0f, 90f, 0f);

to

transform.localRotation = new Vector3(0f, 90f, 0f);

and Unity spat this at me;

error CS0029: Cannot implicitly convert type ‘UnityEngine.Vector3’ to ‘UnityEngine.Quaternion’

Or in other words, ‘Unity says no!’

Being that I’m almost certain that I’ll never truly understand a fraction of the deeper maths theory behind this, should I just accept it and move on? I’m wondering if that’s what most hobbyist developers do?

I first came across the mysterious Quaternion in a Youtube tutorial a few weeks back. It was aimed at beginners, but this stood out as it was the one thing that the trainer didn’t even attempt to explain, he just said and here is how to set the rotation, you need to use a Quarternion.Euler, as if that should be obvious. My reaction was - what the hell is that??? How is this different to just using a Vector3?

The Unity manual example didn’t exactly shine much light on it either. It actually gives an example of creating a new Vector3 with the floats that represent x,y and z axis, then implanting that into a Quaternion.

So, the transform.localRotation can’t be directly set with a vector3, but it can be set to a Quaternion.Euler, which in turn can be populated using a Vector3?

Man, all I want to do is rotate a 3d model 90 degrees on one of it’s axis then celebrate with a cup of tea! Instead, it’s 3am and I’ve got a headache from trying to understand what this is all about! :slight_smile:

But briefly, back to ‘Order Matters…’ From my point of view, does it? I’ve set it and it worked. I use the magical Quaternion that I truly don’t understand and my spaceship is rotated however I want it to. Unless you’re doing something truly complicated in Unity, do you ever need to know any more than that?

Quaternion is a class in Unity with a lot of public static methods. Euler is a method in that class. This works exactly the same as all the methods you write for your own classes.

For that matter, Transform is also a class. Each instance of Transform has variables like localRotation, and each variable works just like the variables you make in your own classes.

Each variable has a type declared for it. A variable’s type determines what kind of information it can hold. Most variables store memory references to other objects or values such as int, string, bool, etc. But they can also hold structs, such as Vector3 or Quaternion.

A struct is an ordered set of variables linked together as a cohesive unit. For example, a Vector2 is a struct made of two float values. A Vector3 is a struct made of three float values. A Quaternion is a struct consisting of 4 float values.

So if you have a variable like localTransform that is of type Quaternion, only Quaternion data can go in there.

Imagine that you’re out with a friend and the two of you decide to get something to eat. “What do you feel like having,” you ask, and your friend replies “Twenty seven.” What?! How does that make any sense. It is not the correct reply to that kind of question.

That’s what it’s like when you put the wrong type of data into a variable that’s a different type. localRotation is a Quaternion variable and needs Quaternion data. You can’t just give it a string or an int or a Vector3.

Vector3s and Quaternions may look similiar because they are both structs composed only of floats. In fact, a Quaternion and a Vector4 can look exactly alike because they are both composed of four float values. But they are still considered different types. localRotation needs Quaternion data and only Quaternion data will do.

It would be simple enough to say:
localRotation = new Quaternion(wVal, xVal, yVal, zVal);
if we knew enough math about matrices to figure out what value should go in each float variable to get previsely the rotation based on what orientation we have now. Most of us do not have the math skills to do this as it involves calculations with matrices involving rules we have not been exposed to.

What’s so hard about matrices? Probably nothing. But it’s more stuff you have to learn. Imagine trying to explain fractions to someone who has only worked with integers and decimal numbers. On the surface, it doesn’t seem like there’d be much too teach. But fractions are quite complex. In addition to being numbers, they are simultaneously expressions (a numerator divided by a denominator), ordering groups, and ratios. There are complex fractions, compound fractions, and reduced fractions. You can perform math operations with them, factor them, convert them, and invert them. They have inverted forms and equivalencies and reciprocals. This stuff is taught to children. It’s not that it’s hard - but it’s more stuff to learn if you want to work with them. I imagine that math with Quaternions is the same way. Justlike finding the cosine of an angle is impossible if no one ever taught you the basics of trigonometry, calculating a Quaternion is impossible to someone who doesn’t know the rules for 4x4 matrix operations.

Fortunately, Quaternions are not the only way to express a rotation. A common way to express rotation of an object is to rotate X degrees along a freeform vector. Another method, and one we are more accustomed to, is to use Euler angles, rotating along three perpendicular axis.

Unity (and lots of other software) uses this Euler Angles technique in their GUI, so we’re pretty used to using three numbers 0-360 to represent a rotation. Unfortunately, behind the scenes, and in code, localRotation wants a Quaternion.

Fortunately, Unity has given us a method called “Euler” to convert Vector3 data into a suitable Quaternion. Just like I learned to convert freeform vector rotation to eulerangle rotation in pre-Calculus, Unity’s mad scientists can use the power of maths to convert a euler angle rotation into a Quaternion.

The function is called Euler() and it is in the Quaternion class. Since it is public and static, we can access it directly through the class (no need to find objects or anything) by typing it as Quaternion.Euler().

Euler() takes in a Vector3 as a parameter and returns a Quaternion result.

Because it returns a Quaternion, we can use “Quaternion.Euler(v3)” (where v3 is a variable storing a Vector3) anywhere we would normally need a Quaternion, such as “localRotation = Quaternion.Euler(v3);”.

1 Like

As for “order matters”, that’s only important if you are rotating more than one axis at a time, which I try never to do. When using euler angles, the order you perform the rotation in can have dramatic differences on the final orientation of the object. As far as I know, other models for expressing rotation (such as Quaternions) do not suffer this problem.

Imagine you have a pencil standing straight up on a desk on its tip, with the tip facing downward. Let’s assume this is euler angle (0,0,0). Now you want to give it a rotation of (90,0,90). Lets look at two scenarios based on the order you rotate them in:

Scenario 1

  1. 90 degrees clockwise on x-axis
    …The pencil tip is now facing you.
  2. 90 degrees clockwise on z-axis
    …The pencil tip is still facing you.

Scenario 2

  1. 90 degrees clockwise on z-axis
    …The pencil tip is now facing left.
  2. 90 degrees clockwise on x-axis
    …The pencil tip is still facing left.

Two completely different results. So it’s important to know what order your instructions will be carried out in. Or you can take my advice and always perform rotations one axis at a time.

$&**&%²

1 Like

Thanks Anthony, two very in depth replies. Am trying to subtly read up on quaternions - am intrigued by this mysterious fourth ‘w’ axis.

So, a few things are intriguing/confusing me at the same time;

  1. Unity, and pretty much every other 3D environment I’ve used (admittedly, at a fairly amateur level) - express 3 dimensional space in the 3 axis that we’re all quite familiar with, obviously x,y and z. Just to give examples, say Blender, Wings 3d, etc. When you perform rotations in the inspector in Unity, or the equivalent in these other 3D apps - under the hood, within the mechanics of the software, are these conversions of figures on 3 axis being translated via Euler Angle technique? I’m sort of picturing it as a way of keeping the GUI reasonable simple for ordinary mortals like myself! I do something relatively simple, like rotate a cube in the transform, but underneath the surface, I’m now envisaging all this maths wizardry going on! It’s quite a humbling thought!

  2. Specifically addressing your comments about not moving something on more than 1 axis at a time. I’m confused by this. If I put in a rotation as a Quaternion.Euler - rotating on the the x and y, like we did at the end of this lecture - it’s a single line of code. Is that not doing exactly the thing you advise you try to avoid? I guess what I’m asking is, when we get told that order matters, then we effectively get taught a technique that seems to ignore doing this in an order, instead seemingly actioning the rotation of both axis simultaneously, and most importantly - successfully, then can you see why repeating the mantra, ‘Order Matters,’ is so confusing? I’m certain it does matter, but I can’t grasp how what we’ve done represents doing things in ‘the right order.’ I was actually expecting that to mean you have to specify in one clear action or line of code the rotation on one axis, and then have to put in another instruction to perform the rotation on the other axis. To me, that clearly represents doing things ‘in an order.’ I suspect I’m thinking about this all wrong, but I’m still confused!

  3. And thank you very much for the whole rotating pencil scenario thing. That makes sense, although I spent far too long staring at a pencil trying to figure it out!!! :slight_smile:

Jim

  1. I do not know, but that is my theory. It’s like the whole degrees vs radians thing. It’s easier to do advanced math in radians, but most people are more comfortable working in degrees because they’re more used to it. So most GUI systems use degrees. But there’s no reason the actual math functions can’t be done with radians. I suspect a lot of Quaternion stuff happens behind the scenes when we use the euler values in the GUI.

  2. I have not taken this course (I’m not quite sure how I found your post) so I can’t speak to what is done in it. I suspect he means that you as the programmer need to be aware of what order things happen when you rotate multiple axis simultaneously, not that you should never do so. Never doing so is my personal advice. I don’t see any benefit to it and I feel like rotating only on one axis at a time gives me more control. To be honest, I tend to use LookAt() and similiar functions whenever possible.

  3. Me too. :slight_smile:


I think reading up on Quaternions is kind of heavy reading with very little gain right now. There’s so much vector math that seems way more important: modifying and scaling vectors, predicting collisions, calculating reflections, applying forces and steering behavior, etc.

If you want to learn more about rotation, you can study yaw, roll, and pitch. That’s basically the style of rotation we are used to.

If you know all about vectors and want to study Quaternions, I suggest first studying math using Matrices. Quaternions won’t make much sense unless you can do basic math operations with a 4x4 matrix abd this skill will be useful for other advanced things, too, one day.

Matrices are the next section of a math/physics e-book that I was reading awhile ago. I just can’t bring myself to go back to it.

If you are interested, Jorge Rodriguez and The Coding Train are my go-to youtube sources for game-related math subjects.

Privacy & Terms