I am making a game where the player can climb any surface.
When the player collides with a surface i get the normal of that collision. This is the direction the players "up" vector should align with:
Now, unity provides a handy method to convert two vectors to a rotation:
Quaternion.LookRotation(forward, up);
It takes the up vector and a forward vector. As i mentioned i already have the up-vector. My issue is how i get the forward vector.
My current solution is to calculate the forward vector by flipping some axis in the normal:
normal = collision.contacts[0].normal;
Vector3 forward = Vector3.zero;
forward = new Vector3(0, -normal.z, normal.y);
transform.rotation = Quaternion.LookRotation(forward, normal);
This looks okay in most situations:
But when the player collides with a surface where the normal only has a x-value the forward vector is 0,0,0:
I know i have to take x-component of the normal in to account aswell to avoid this situaion but i am not sure where to plug it in.
Consider this more of a Unity based question that involves the math functions provided by the engine, as oppose to a pure math related one. But any answer is of course appretiated.
Check for magnitudes of vector components.
Then make component with the smallest absolute value zero, and exchange the largest and the second components, negating the largest. This approach produces valid perpendicular for all non-zero vectors
For example, for case
Abs(n.x) >= Abs(n.z) >= Abs(n.y)
make
Perp = (n.z, 0, -n.x)