Hi, I’m trying to make a twin-stick player like in Nuclear Throne, meaning a side-facing sprite with a gun that rotates around him 360 degrees. The graphics x-flip when past 90/-90 degrees, but the x-flip/angle combo isn’t working as I’d expect…
The gun’s image (on a quad) is a child of my “gun” object, which is the game object I apply the rotation to. In the normal orientation, the “gun” is positioned at the arm-pivot point, and rotation happens around this point just fine.
When flipped, the gun rotates from a weird random pivot (not on the arm). When I look at everything in the scene view, the gun is at the correct arm-pivot point, like it should work. This is the confusing part if I change the angle of the gun object by a tiny amount (0.00001) in the properties window it snaps into the correct position and orientation.
So I don’t see any issues with the math, and unity “fixes” it when I edit the angle directly in the properties window - any ideas why the rotation gets messed up in-game?
(note: While looking for an answer, I only found the suggestion to rotate around the Y-axis instead. I’d prefer to not do this for a variety of reasons, including my quads disappearing and my z-ordering getting flipped.)
EDIT: Since you asked, here’s some code. It’s split between two scripts (one for the character, another for the gun). Here’s the character’s x-flip code, the facex var is created from the inputs, so you face the way you are moving/shooting. FlipX is a constant with values (-1, 1, 1).
if (facex != 0 && facex > 0 != transform.localScale.x > 0)
transform.localScale = Vector3.Scale(transform.localScale, FlipX);
And here’s the code on the weapon which rotates it (and its child with the image quad).
float ang = Mathf.Rad2Deg * Mathf.Atan2(aim.y, aim.x);
if(ang > 90 || ang < -90)
ang = Mathf.Sign(ang) * 180 - ang;
Quaternion q = Quaternion.AngleAxis(ang, Vector3.forward);
transform.rotation = q;
I think the math is correct, because as I pointed out things get ‘fixed’ when I enter identical values at runtime in the inspector. It’s almost like there is some kind of Apply() method I need to call… but that isn’t the case right?