Exactly. Funny enough that if you actually look at the OPs solution, it’s not really about fixing “the error” but to provide a resting direction and as we can see, it’s not the identity rotation but he wants to face to the right.
This condition btw looks like it makes no sense:
if(axisCombined >= 0.1f || axisCombined <= 0.1f)
and yes, under normal circumstances this makes absolutely no sense. However it’s an implicit NaN check. So this is essentially a hacky solution to exclude the case where both input axis are 0 (because he does axisCombined = axisY / axisX;). That’s really an ugly and obfuscated solution which I would never want to use.
What exactly makes the identity rotation the right return value? Keep in mind this rotation is used as an absolute rotation. So just using identity could be a solution, but it won’t necessarily fit every problem. Actually it rarely would. As I just said, it wouldn’t even be a solution in the original post.
Errors and warnings are your friends. The compiler / CPU / computer does not know your intention and what you need that value for. However if you give it an impossible task, he should complain about it and not make up some answer as it sees fits.
Note in case of Vector3.Normalize which returns Vector3.zero if the vector is too small to normalize, this makes more sense for two reasons: Checking if an error occured can still be done because properly normalized vectors are never 0. So the “error state” is preserved and proper context specific error handling can be done afterwards. Also in case of normalization, when the input vector is almost 0 and in essence doesn’t have a direction that is to be preserved, it makes sense to just “round” it to 0 because the information is already / or about to get lost.
By returning the identity rotation you could not distinguish between a valid rotation or an error afterwards without looking at the input. When you suddenly return the identity rotation the orientation would most likely snap to a completely different direction unless you happened to look into the identity oritentation by accident. Computers should communicate user errors properly and the user should avoid them. That’s why System.Math.Acos returns an error (NaN) when you pass it a value that is outside the range -1 to 1. You could say it should just clamp the input so it always returns a valid angle, but the function simply is not defined outside the range and such a result would just be wrong.
The method is in the unity dll so I can’t rewrite it and add a wrapper. Also, no, I don’t mind "mild inconveniences, I do this full-time. It’d just be nice if I could select to disable the logs.
An accessible method that takes the same inputs, provides the same outputs, and has a catch for look direction of zero - that’s as difficult as this needs to be; but it does NEED to be that difficult because it is impossible to find any angle between two points when those points are the same.
public static Quaternion LookRotation( Vector3 fwd, Vector3 up ) { return fwd == Vector3.zero ? Quaternion.identity : Quaternion.LookRotation(fwd,up); }
So using vectorChange == Vector3.zero is closer to your intent than .Equals(). Personally, I find a hidden epsilon to be repugnant and overloading == to gloss over the concept of floating point error to be one of Unity’s most annoying code smells. Your approach to use an explicit epsilon is the right way to go.