Rotation between two points

I am developing this small Unity app. that is receiving information about two 3D points wirelessly from another source.

Consider these two points being, pointA and pointB – where pointA is the position of my GameObject in Unity and pointB is to be used to generate its orientation. The rotation direction in this case is from pointA to pointB.
The questions is: How do I generate the rotation of my GameObject here?

I read somewhere that I could generate such rotation between two points by just using (pointA - pointB) as the direction and then using Quaternion.LookRotation.
However, I do not understand what’s happening behind the scenes and it’d be great if somebody could explain the vector maths behind it (e.g: how do I get direction by just subtracting two vectors?)

2 points in 3d space is not enough information to orient it.

There needs to be more info.

You want to stand at pointA and ‘lookAt’ pointB?

Well… long explanation ahead:

OK, well what is looking at? Usually you select a vector to be a looking direction (a needed piece of information). In unity this is usually <0,0,1> (the blue arrow pointing out of a gameobject when you highlight), this value is accessible as ‘transform.forward’.

Furthermore, when you look at something… you could stand on your head, lay down, or stand up right. There’s 360 degrees of freedom around that forward vector to ‘lookAt’ something point. So you ALSO need the information of what is the ‘up’ direction when you look at that. This is usually <0,1,0> and is accessible as ‘transform.up’.

In unity most of the Quaternion helper methods presume that you use the ‘transform.forward’ as the ‘facing direction’. You should always set up GameObjects so that they visually look in that direction. So if you have a model, it should be set up with the blue arrow facing in the direction of the head. If you can’t do that, you can child it in a parent gameobject, orient it correctly inside so it faces in its parents forward (this might result due to an art program having a different orientation standard. 3ds max is one of these…).

Now quaternions are like vectors in that they aren’t an actual rotation. It’s an amount of rotation. Like Vector3 isn’t a position, it’s a direction and magnitude. But if you presume that <0,0,0> is some origin, then the Vector3 can represent a position. Quaternion too needs this… it needs an ‘origin’ rotation. The ‘zero’ quaternion isn’t 0 though, its Quaternion.identity. This means you have NO rotation. Which results in forward being defined as <0,0,1>, up is <0,1,0> and right is <1,0,0>. The Quaternion rotation is the amount of rotation that would be applied to those vectors so that those vectors face where you expect.

This is what Quaternion.LookRotation facilitates. It’s shaped as:

Quaternion.LookRotation(Vector3 forward, Vector3 up)

Used the way you need you’d do:

var dir = pointB - pointA; //a vector pointing from pointA to pointB
var rot = Quaternion.LookRotation(dir, Vector3.up); //calc a rotation that
transform.rotation = rot;

What the function is doing is determining what rotation is needed so that when appllied to a transform in default ‘identity’ position (no rotation), would result in transform.forward equaling the forward vector passed in, as well as the transform.up vector equaling what the up vector passed in is…

Of course, you might pass in a direction that isn’t adjacent to up. In that case the function prefers the up vector, and will force that first and foremost.

Meaning if you say passed in a forward of <1,1,1> and up as <0,1,0>, it’d actually face in the direction <1,0,1> (normalized of course).

Getting into the actual maths of it is fairly complicated since Quaternions are actually a complex number system in the form:
xi + yj + zk + w

Where i, j, and k are imaginary numbers (square-root of -1), but are not equal. Rather they meet these requirements:

And that:

When this complex vector number system is normalized (has a magnitude of 1) it acts like a axis/angle representation. The position on its complex number system when projected into the real-number system results in a vector that could be observed as an ‘axis or rotation’ and the complex part results in a torque on that vector… or amount of rotation around that axis.

Anyways, getting into the maths of it is a bit out of the scope of this thread.

tldr;

You’re creating a rotation that looks in the direction of ‘forward’ while standing in an orientation so that up is the direction of ‘up’.

Your ‘forward’ should be ‘pointB - pointA’, and up is most likely Vector3.up or <0,1,0>

3 Likes
    Vector3 clickPosition = -Vector3.one;

    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit;

    if (Physics.Raycast(ray, out hit))
    {
        clickPosition = hit.point;
    }

    [B]Vector3 direction = GameObject.Find("Player").transform.position - clickPosition;
    Quaternion bulletRotation = Quaternion.LookRotation(direction, Vector3.up);[/B]

    Instantiate(MyWeapon.Bullet, GameObject.Find("Player").transform.position, bulletRotation);

Get a vector 3, direction (by subtracting two points from each other). Than use Quaternion.LookRotation to find the rotation you are looking for.

This works because of math and logic. If you subtract two numbers, you get the difference between them (aka. 5 - 3 = 2, the difference between 5 and 3, is 2). If you use this same logic for Vectors, you find the difference between two points, and this is the direction you need to go in order to make the two points the same. Quaternion.LookRotation is a bit more complicated, as it is dealing with 4D. If you want to learn about Quaternions, I’d recommend this video:

Hope this is helpful to someone.

So… using LookRotation, the answer that was given 8 years ago.

2 Likes