I spent ten hours today trying to get a game object to rotate to my liking.
The hours of troubleshooting spent on this one definitely feel as though they’ve caused me some brain damage. I did a ton of google searching, and I’d like to give a shout out to the guy in 2017 who asked a question like mine and then answered his own question six hours later. I replicated his formula and it worked. I didn’t understand why, so I spent a truly discomforting majority of my day picking it apart, and I’ll demonstrate this by repulsing every math-averted person in the room.
Long story short, rotations in Unity are tricky, made trickier in this scenario because I’m designing a 2-D game in a 3-D space. I want to rotate my Player toward my Enemy, right? So I need to tell my Player the angle at which to point. We need to make a right-angle triangle in order to find these out, and surprisingly, there are only two major pieces of information needed.
- Difference between Player and its Target on X-Axis (see xDiff)
- Difference between Player and its Target on Y-Axis (see yDiff)
With these, we can construct the triangle above. Since we’ve made a right-angle triangle, one of the angles is already figured (90°) and all we have to find is one of the remaining two. For this, Sines, Cosines and Tangents are used, or more specifically, their inverses. Sines, Cosines, and Tangents are the ratios of two corresponding sides of said triangles. Their Inverses are the angle measurements that we need.
Since a triangle is 180° and we already have the 90°, that only leaves 90 remaining, so finding out EITHER of the two remaining angles tells you both of them. So we just need one angle. Let’s choose Angle A. Can you look at the figure below and tell why Inverse Tangent is our easiest option?
Inverse Tangent takes the ratio of the Opposite side over the Adjacent side lengths, and returns an Angle measurement. We already have those two sides, we don’t need to find the Hypoteneuse.
So, referencing the detailed diagram at the start, our Inverse Tangent for Angle A is yDiff (Opposite) divided by xDiff (Adjacent). Plug these into Unity’s pre-made Inverse Tangent (Mathf.Atan) formula and you’ll get an angle that gets you pretty close to finished. If you put this into your game and tested, you’d find your Player only rotating in one half of the world.
Luckily, someone’s been here before us. That someone is the reason Mathf.Atan has its own second variation. Mathf.Atan2 returns the radian measurement and allows for a full 360° range instead of the 180° that Atan was offering us. This is noted below in the Console section as Atan shows its limited range while Atan2 offers the full 360°. Mathf.Rad2Deg is used to convert the radian measurement into degrees, which is easier for us.
If you’ve implemented this, you may have noticed there’s something still missing. We’re rotating in a circle, and normally, 0° is facing to the right. But our Player is facing 90°, and our Enemy is facing 270°, so we’ll need to add an offset to our Angle A measurement so that any characters face the right way. And that’s that! Functional 2-D rotation in a 3-D space.
Piece of cake! It can only get easier right? Maybe the next time I disect a feature it’ll only take 5 hours instead of 10.
- Take difference between Player and its Target on X & Y Axes
- Mathf.Atan2(xDiff, yDiff) and convert to degrees
- Insert whatever necessary offset
- Rotate and enjoy!!