Btw, if you’re interested, here’s a bit of a short history.
Mathf.Atan2 is just a slightly more advanced version of the Atan, which is just a abbreviated name for arc tangent, nowadays a standard issue in any decent math library.
Ordinary tangent (Mathf.Tan) in trig entraps a powerful relationship between a sine and a cosine, namely tan(theta) = sin(theta) / cos(theta)
and thus speaks of the ratio between X and Y offset, in other words, it captures the slope of the line – where tan(0) = sin(0) / cos(0) = 0 / 1 = 0
, and tan(45) = 1
(X and Y are the same), then tan(90)
has to be undefined (and actually not infinity, contrary to popular belief, but it’s practically similar), because cos(90) = 0
.
Arc tangent, similar to its Arc sine and cosine friends, inverts the result back to angles. So if you can get the offset by doing Mathf.Cos(30)
for X and Mathf.Sin(30)
for Y, and slope by Mathf.Tan(30)
, then you should be able to do Mathf.Acos(X)
or Mahf.Asin(Y)
to get your 30 back.
And this should work the same for Atan as well if you do Mathf.Atan(Y/X)
, however(!), this will lose a vital component of the original deltas, their actual signs.
If you pay attention, Mathf.Atan accepts just one argument (as it really should, trigonometry-wise), but this makes the result of y/x ambiguous, because if there’s a minus, you can’t tell whether it was -y/x or y/-x, and well if it’s a plus, you can’t tell whether it was y/x or -y/-x, and so the result will live in some random quadrant which you’d have to determine by analyzing the actual signs, which is what we used to do back in the days without Atan2. Yes I’m that old.
And this is the actual, old school reason, why this function accepts its arguments in the y, x order. It will probably be lost in time, like tears in rain, once the AI starts to build our software.
All in all, Mathf.Atan2 is ubiquitous in cases when you have two coplanar points and want to compute an absolute angle between them. You could, in a more general (3D) case, use Quaternion.FromToRotation to get a much more robust quaternion for the same thing.
var target = myCamera.WorldToScreenPoint(myMouseCoords);
var rotCenter = myCamera.WorldToScreenPoint(myObject.transform.position);
var direction = (target - rotCenter).normalized; // we have to normalize a direction
myObject.transform.localRotation = Quaternion.FromToRotation(direction, myObject.transform.parent.forward);
// here you basically compare two directions, the other being your object's identity direction
FromToRotation does this btw (this is my recreation, not an actual implementation)
static public Quaternion FromToRotation(Vector3 dir1, Vector3 dir2) {
float w = 1f + Vector3.Dot(dir1, dir2);
Vector3 xyz = Vector3.Cross(dir1, dir2);
return new Quaternion(xyz.x, xyz.y, xyz.z, w).normalized;
}
Note that there is problem with it in Unity when the directions are directly opposite to each other. It’s a bug that won’t be solved any time soon, because it seems that I’m the only fool to actually use quaternions to such an extent.
You can see from this that it makes little sense to use if your context is 2D. Atan2 is cheaper and lighter to use, although not by much.