Difficulty understanding LookRotation

While I understand that the Quaternion.LookRotation function generates a quaternion from a specified target’s transform.position, I’ve often seen the difference between the target position and the gameObject’s position used to rotate the gameObject.


Quaternion.LookRotation(target.position - transform.position)

rather than the expected


I’m having difficulty understanding why this is the case (or why it works at all).

The LookRotation method takes a direction as its parameter. A direction can be considered the straight path from 0,0 to the vector’s end position. It’s also known as the relative position. So on a 2D plane, a direction vector of (2,1) will, add 2 to x and 1 to y.

The starting position does not need to be (0,0), in fact, the direction from (3,0) to its target (5,1) is still (2,1), that is endPoint - startPoint.

So, in short, if you use Quaternion.LookRotation(target.position) you are computing the direction from the world origo (0,0,0) to target.position, whereas using Quaternion.LookRotation(target.position - transform.position) computes the direction from transform.position to target.position.


My knowledge of Quaternions is limited to knowing that they can be considered a 4D gimbal. You know, with 4 of those moving circles instead of the three shown on the wikipedia page. That’s been enough to peacefully co-exist with them… though I have been using euler angles.

I’ll try to explain the concept of direction more thoroughly, then. Consider vectors A and B in a 2D plane:


Vectors can be considered to be many things. To name a few examples: direction, length and position.

A direction can be defined as a way to get from somewhere to somewhere else. In our illustration, Vector A is a direction but Vector B is not a direction. Why so? An example will illustrate the situation.

Let’s say we are standing at (3,1) and want to go to the direction Vector A points to. So, we take two steps right, and one up. If you now draw the path we took, you would find that the path is indeed parallel to Vector2. If we tried the same with Vector B - taking half a step left, then two up - the two lines would not be parallel. This is because Vector B does not start from the origin, (0,0). Now we can easily draw the conclusion: All directions must have their starting point at the origin: (0,0).

How can we then find what direction our Vector B has? The answer is simple: we need to move the vector so it begins from (0,0). In our case, Vector B needs to be moved half a step right, and half a step down, so we subtract the start point from the end point. Our new direction vector is (-0.5 -(-0.5), 2 - 0.5) = (0, 1.5). If we now move from any starting point using that direction, we will always move straight up, and the lines are again parallel.

Normally directions are given in their normalized form. That is, all values are within the inclusive (0,1) range. This is because there always exists a scalar that gives any parallel direction of a different length. The way this normalized direction can be computed, is using a unit circle (a circle with a radius of 1), and computing the intersection point of the direction vector with the unit circle. The intersection point of any direction and a unit circle is the normalized direction vector. If there is no intersection, then the direction vector may be multiplied by an appropriate scalar. Computing the intersection point is basic trigonometry. My calculator says the normalized direction of Vector A is (0.89, 0.44). The scalar to get Vector A form this normalized direction is ~2,247.