Can someone please explain Quaternion eulerAngles to me?

I used to have Vector3 everywhere, and my player movement was totally fine. However, now I’m using a script to get more fluid animations, and that required me to move everything over to Quaternions and now my rotations are fine, but since actual movement is still Vector3, I run into trouble:

// This works fine:
 
cc.Move (transform.forward * forwardMotion * moveSpeed);
 
// But this doesn't generate any movement... why?
 
Quaternion fwd = Quaternion.LookRotation(transform.forward);
cc.Move (fwd.eulerAngles * forwardMotion * moveSpeed);

I do not understand why there is a difference in results using the above code.

Also, using Debug.Log on the following:

		North = Quaternion.LookRotation (-transform.right);
		East = Quaternion.LookRotation (transform.forward);
		West = Quaternion.LookRotation (-transform.forward);
		South = Quaternion.LookRotation (transform.right);

I get:

(0.0, -0.7, 0.0, 0.7)
(0.0, 0.0, 0.0, 1.0)
(0.0, 1.0, 0.0, 0.0)
(0.0, 0.7, 0.0, 0.7)

Which I also do not understand (where the 0.7, for example, since it should all be at least right angles).

Quaternions are for rotation, they store rotation as 4 values that define complex numbers.

The eulerAngles property is that rotation returned back as pitch/yaw/roll.

This is NOT the ‘forward’ vector. It is the pitch, yaw, and roll.

Continue using transform.forward if you need the forward vector.

If you have a Quaternion rotation and no transform to get a forward from, then you can rotate a vector like so. Here you’d get a forward vector:

var fwd = someRotationQuat * Vector3.forward;

Vector3.forward is what forward would be if no rotation was applied. So if you rotate it by some rotation, that’s where it would be if a Transform was rotated.

Thank you! Multiplying all my Quaternions with Vector3.forward got my old functionality back and moving the CharacterController now works again.

I must admit, I still really don’t understand Quaternions, and what differs pitch, yaw and roll EulerAngles from Vector3, but from searching online, I understand that this is a topic quite common to confusion. :slight_smile:

It’s just a different way of storing the rotation values.

The actual values may not make sense to you. But it’s not important. Just think of a Quaternion as being a single value that represents 3-dimensional rotation.

You can represent a rotation as 3 values Pitch/Roll/Yaw signifying the angle of rotation around the 3 primary axes.

You can represent a rotation as a 4x4 matrix that contains the up, right, forward vectors which defines rotation.

You can represent a rotation as a Quaternion that stores the 4 scalar parts of 3 complex numbers that define an axis and an angle around that axis, which defines rotation.

You can represent 2d rotation as an angle off some primary axis (<1,0> usually), in either degrees or radians.

You can represent 2d rotation as a 2d direction vector.

You can represnet 2d rotation as a 3x3Matrix with up and right vectors in it.

Rotation is just an orientation in space. How you want to represent it is arbitrary. Quaternions are just ONE method of many. And being mathematical constructs, they have mathematical rules about them. They perform better than eulerAngles because their construct’s rules are more adept at being manipulated. We can multiply by quaternions because quaternions have a definition for multiplication. Euler angles do not.

I would like to point out, the code you originally posted though:

Quaternion fwd = Quaternion.LookRotation(transform.forward);
cc.Move (fwd.eulerAngles * forwardMotion * moveSpeed);

if you went and changed that to:

Quaternion fwd = Quaternion.LookRotation(transform.forward);
cc.Move (fwd * Vector3.forward * forwardMotion * moveSpeed);

What’s the point? you already HAVE the forward vector, it’s up there in ‘transform.forward’.

Thank you for the explanation!

My original post was just the gist of my problem. In reality, I’m storing the four allowed movement directions (the North, East, West and South I posted) in Quaternions for a unity script that wanted that data type in order to get smooth rotations for me (and hopefully smooth screen shakes in the future). What I pasted was a stripped down version of me taking that current Quaternion direction and trying to walk my player along that, well, rotation apparently.

You don’t really have to understand Quaternions to use them. I certainly don’t (to this day I have no idea what a Quaternion’s wxyz’s mean, only that they are -1…1 and unrelated to the Euler angles). Fortunately, Unity’s Quaternion class has helper functions that make understanding Quaternions not really necessary.