In Unity, a Transform's rotation is stored as a quaternion. These work similarly to vectors, but have four components:
x, y, z, and w. These components are
interdependent, and work together to define any rotations
that an object might need. One of the most important
things to remember about dealing with quaternions, is that since the x, y, z, and
w components work together, you should never
adjust them individually. Thankfully, Unity has
many built-in functions to make managing quaternions easy. The system for managing rotations that you are probably
already familiar with, is called Euler angles. The rotation values shown in
the Inspector use this system, as it is slightly
easier to understand. Euler angle rotation
is based on a rotation around each of the
x, y, and z axes. You might be wondering
why Unity uses quaternions if Euler angles are
easier to understand, especially since Unity
converts the quaternions to Euler angles for the Inspector. Suffice to say that Euler angles are subject to something
called gimbal lock, which can prevent incremental
rotations from working correctly. Luckily, since Unity stores
rotations as quaternions, which are not subject
to gimbal lock, we do not experience this problem. Let's take a look at
some of the functionality that is available through
the quaternion class. We will start with the
LookRotation() function. Here we have a Scene set up
with a character and an orb. The character has a script called
"Look At Script" attached to it. The orb has a script called
"Motion Script" attached to it. The Motion Script simply
moves the object side to side based on the horizontal input axis. The LookAtScript has a public field
for a target Transform. And in the Update() function,
we will be using LookRotation() to cause the object to
rotate to face the target. The LookRotation() function
takes in a Vector3. It returns a quaternion rotation
aligned with a Vector3 passed in. By calculating the relative vector
between the object and the target, we can make the object's z-axis
point towards the target. This works in a similar
way to transform.LookAt(), but utilizing quaternions
sets the rotation explicitly. It is also worth noting
that we can pass in a second Vector3 to the function. This Vector3 tells the function which direction is considered up. Back in the Unity Editor,
let's run our Scene. We can see that no matter
where we move the orb, the character turns to face it. The next function we want to
look at is the Slerp() function. "Slerp" is short for
"Spherical Interpolation". It is very similar to
the Lerp() function, which stands for
"Linear Interpolation". The big difference between the two, is that Lerp() will interpolate
evenly between two quaternions while Slerp() will
interpolate on a curve. The result is that Lerp() will
provide an even change over time, while Slerp() will start and then
slower and be faster in the middle. We have here a Scene with
another character and orb. The character has no
scripts attached to it. The orb has a "Gravity Script"
attached to it. This Scene we utilize Slerp(),
and some forward movement, to achieve a gravity orbit effect. In the Gravity script,
we have a set up similar to the LookAt script from before. Again, we have a public field
for our target Transform. We are also calculating
the relative vector between the object and the target. Those this time we
are adding an offset to account for the orb's height. We are also calculating the
LookRotation() like before, except we are not
storing it in the rotation of the object's
Transform this time. Instead we are storing it in a
quaternion variable named "rotation". We are then storing
the local rotation of the object quaternion
variable named "current". After that we are using
the Slerp() function to slowly turn the object
to face the target. The Slerp() function reads
in the current rotation, the end result rotation, and the
speed it should interpolate, or turn. The fact that the rotation
doesn't happen immediately, but over time, is the key
to making this example work. After we turn the object
slightly towards the target, we move it forward a little bit. Back in Unity, we can run
our Scene and see the result. The orb is always moving forward, and turning to face the target, which in this case
is the character. This gives us a nice
smooth orbit effect. The last thing we
are going to look at is the identity property
of the Quaternion class. Setting a quaternion
to Quaternion.identity, will effectively set its Euler
rotation to 0, 0, 0, or no rotation. There are more functions
in the Quaternion class that you can find in the
documentation linked below. The most important things to
take away from this lesson, are that quaternions
are the best way of dealing with rotation,
and that you should never alter the components independently. There will always be
some functionality that you can use instead.