While the Looking At node actually contains an answer to your problem, it probably won’t solve it. The issue is that the Looking At node also takes control over all three axis. You could say that it assumes to have exclusive control over an objects rotation, which is obviously not the case for a player controlled character.
- calculate v = cross(up, normal)
- calculate β = arcsin( || v || ), invert if necessary
- rotate your object by β around v (not yet exposed in nodes, but I think it should be)
Let’s assume that both vectors, the surface normal and your characters up vector are unit vectors (this simplifies calculations a little).
If you calculate the cross product of these two vectors (let’s call the result v), you will get a vector, which is perpendicular to both, your normal and your up vector. Now imagine those three vectors. If you want your up vector to align with the normal vector, you would have to rotate it around v by a certain amount. In other words, v is your rotation axis.
Now we need to calculate the angle β between your normal and up vector. For this, the following equation can be used:
|| v || = sin(β) • || normal || • || up || , where || ~ || represents the norm (or length) of a vector.
If up and normal are unit vectors are unit vectors, this simplifies to:
|| v || = sin(β), or β = arcsin( || v || ).
However, β will always be positive, but I think this might not be an issue (try inverting if necessary)
After you got your axis and your angle you should be able to rotate your object by β around v. The transform class contains a method to do exactly that, but it is not exposed in nodes… yet.
Personally I think it should be possible to easily rotate an object around an arbitrary axis in nodes, so I will look into creating a corresponding node tomorrow.
You could also use
β = arccos( <normal, up> / ( || normal || • || up || ) ) = arccos( <normal, up> ), for unit vectors.
<•, •> represents the dot product.