Rotate transform so that 2 of its vectors point the same as other 2 vectors?

Lets say I have a hand, and i want to position it as it would be grabbing a rigidbody.

I can position it at the grabbing point.
I also have the normals poiting out from the surface of the colliders

I need to align the right vector of the hand with the normal
and at the same time
align the up vector of the hand with the world down.

How can i do both of these?

7931962--1013347--upload_2022-2-28_15-54-28.png

as you can see the hand right points like the normal
and the hand up points like vector3.down

Well there is a method on Quaternion to create a rotation from 2 vectors:

It’s LookRotation which takes a forward and an up.

You have an up and a right… of course mathematically this would be enough, but why do all the complicated maths of quats, when we have this forward/up version gifted to us in the lib.

So all we need is to get a forward from the right/up.

And we do that by the cross product of the right/up:

So… cross right/up to get the forward. Then pass forward/up to the Quaternion.LookRotation. And that’s our needed rotation.

[edit]
Sorry I should point out order of operations matters on Vector3.Cross, as the link talks about the “handedness” of Unity.

So you’re going to want to pass your ‘right’ as the “lhs” (first parameter), and your ‘up’ as the “rhs” (second parameter).

Like so:

transform.rotation = Quaternion.LookRotation(Vector3.Cross(thenormal, Vector3.down), Vector3.down);

If one does it backwards… all you get is -forward rather than forward. So if my code results in backwards positioning… well, I did my order of operations backwards. None of us are perfect.

2 Likes

Hey thanks for the answer, it works perfectly!