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.