Rotation in Unity. Simple!

Deep dive into the maths that goes behind rotating a character in Unity

Seemanta Debdas
Eincode
6 min readNov 2, 2022

--

Before looking at Unity Specifics(Built-in methods to help us handle rotation), let's look at how things work behind the scenes by rotating a character toward a specific destination.

Scene Setup

Here, I have a simple scene where the character will move toward the pot when we press "Space".

Here's the code to achieve this: (A link to the complete project is provided in the Resources Section)

Code for moving the character toward the pot

As you can see, the character doesn't face the pot while moving toward it.

A simple fix is to make the character's forward vector (blue arrow) face the pot. Let's first see how we can rotate a vector to achieve that.

Rotating a vector

To rotate a vector by an angle, we can manipulate the components of the vector(x,y, and z) using sine and cosine functions.

Say we have a vector (x₀,y₀), and we want to rotate it by angle θ to get the resultant vector (x₁,y₁); then we can use the following formula to do so:

x₁ = x₀ cosθ — y₀ sinθ

and

y₁ = x₀ sinθ + y₀ cosθ

In our case, the vector we're trying to manipulate is the character's forward vector, and we're trying to face it toward the vector pointing toward the pot.

We can quickly get the vector pointing towards the pot from the character by subtracting the Position of the pot from the character's Position (make sure to normalize it).

While this might seem daunting at first, all we need to do is use the formulas in the code like this:

Notice that we're considering x and z instead of x and y since the vector we want to rotate(forward vector) lies in the xz plane(the y value in this plane is always 0).

Check out this excellent tutorial to learn more about how the formula is derived! Just a heads up, the formula can also be represented in the form of a matrix. It's called a Rotation Matrix.

Now that we have the formula to rotate the vector, all we need is to provide the angle to rotate it by. This is where Dot Product comes in!

Dot Product

In Game Development, Dot products help us determine where one Game Object is about another Game Object.

For example, The Dot Product between the forward vectors of two characters tells us whether they are facing each other or away from each other.

Dot Product for different orientations of two vectors

Vectors perpendicular to each other always yield a dot product of 0.

Vectors having an obtuse angle (an angle more than 90) will always yield a result of less than 0. Vectors directly opposite each other have a dot product of -1.

Vectors having an acute angle between them(an angle less than 90) will always yield a result of more than 0. Vectors pointing precisely in the same direction have a dot product of 1.

We can calculate the dot product of two vectors using two formulas:

1) a · b = |a| × |b| × cos(θ)

where |a| and |b|are the magnitudes of vector a and vector b, respectively.

OR

2) a · b = ax × bx + ay × by

Notice that using equation 1, we can quickly figure out the value of θ by rearranging the function like this:

θ = cos⁻¹ [ (a · b) / (|a| |b|) ]

Now that we know how to get the angle between two vectors mathematically, we can quickly implement this in code like such:

To put this to work, we'll create a Rotate function and call it from the Start. The Rotate function will set the forward vector according to the rotation we get from the RotateAboutAngle function.

Now, if you test it out, it works!

But not always. If I move the pot to the other side of the room, I notice that the character isn't pointing in the right direction:

So, what's going wrong?

Well, Unity essentially uses Left Handed coordinate system, i.e., every positive rotation will turn it anti-clockwise. Our current system cannot determine whether the character should rotate clockwise or anti-clockwise about the angle to face the pot.

Even though we can figure out the angle between the two vectors and whether the vectors generally point in the same or opposite directions using the dot product, it is not applicable when figuring out whether the character should rotate clockwise or anti-clockwise.

This is where Cross Product comes in!

Cross Product

The Cross Product calculates the perpendicular vector of the two vectors(perpendicular to the plane containing the two vectors).

In this simulation, the vectors u and v lie on the XY plane. Changing the vector v from left to right of the vector u changes the z value of the cross product(mainly the sign).

Check out more about this fantastic simulation by Tim Brzezinski here: GeoGebra Link.

In the game, notice that when the box is on the right, the cross product between the character's forward vector and the direction vector from the character to the pot is positive.

And when the pot is on the right, the y value of the resultant vector is negative.

We can use this data to specify whether to rotate in a clockwise or an anti-clockwise direction.

First, let's modify the RotateAboutAngle function to accommodate another parameter: bool isClockwise. If isClockwise is true, then:

  • Convert the angle from radians to degrees by multiplying the angle by Mathf.Rad2Deg.
  • Subtract the angle from 360°. Instead of turning clockwise, we will rotate anti-clockwise up to (360°- angle) so that it seems we rotated in the clockwise direction by angle degrees.
  • Convert the angle back to radians by multiplying the angle by Mathf.Deg2Rad.

Modify the Rotation method like such:

Here we're checking whether or not the y-value of the resultant vector of the cross product is more than zero. If yes, then we rotate clockwise. Else we rotate anti-clockwise.

Now, if we test it out, our character points correctly wherever we place the pot!

In the next part, we'll look at the Unity Specific methods to handle rotation!

Conclusion

If this simple Rotation tutorial piqued your curiosity, you should consider opting for The Complete Unity Guide 3D- Beginner to RPG Game Dev in C# offered by Eincode. This course features among the most immersive and practical resources out there.

This course is curated by experienced software engineer and freelance developer Filip Jerga. This course starts with the fundamentals. Then, it progresses gradually to eventually take its subscribers through the journey of developing their own RPG game using Unity 2020 and C#.

Cheers!

Debdas

--

--

Seemanta Debdas
Eincode

Game Dev enthusiast contributing to the Gaming Industry!