Unity 2D Platformer - Arm Rotation and Transform.localScale Inversions

I’m making a 2D platformer game where the player has an arm that points towards the mouse cursor. This mechanism is used to aim the player’s weapon. However, I am experiencing some glitches when rotating the arm.

I know the reason why I am getting these errors: The arm (in the hierarchy) is a child of the player, and what I’m doing to the player is flipping (inverting) its transform.localScale.x value whenever it moves in a specified direction, so that the player sprite looks in the given direction. Since the arm is a child of the player, its own transform is flipped as well, making it look in the same direction as the player, which is what I want. However, this causes some errors with the arm rotation. Since the arm’s transform.localScale.x value is flipped, the rotation is all messed up, and I can’t figure out how to solve it.

I’ve seen some online tutorials on how to do this, but they all provide scripts that are 99% the same as my own, and they don’t help.

Here are some example scripts for moving the player and arm. They are simplified so that you can read it better.

// Update is called once per frame
void Update () {

	var input = Input.GetAxis("Horizontal");

	if(input > 0) {
		if(!facingRight) {
			ChangeOrientation(gameObject, new Vector3(-1,1,1));
			facingRight = !facingRight;
		}
	}

	if(input < 0) {
		if(facingRight) {
			ChangeOrientation(gameObject, new Vector3(-1,1,1));
			facingRight = !facingRight;
		}
	}

	rbody.velocity = new Vector2(speed * input, rbody.velocity.y);

}

public static void ChangeOrientation (GameObject g, Vector3 changeBy) {
	var newTransform = g.transform.localScale;
	newTransform.x *= changeBy.x;
	newTransform.y *= changeBy.y;
	newTransform.z *= changeBy.x;
	g.transform.localScale = newTransform;
}

And my arm rotation script:

void Update () {
	//rotation
	Vector3 mousePos = Input.mousePosition;
	mousePos.z = 0;
	
	Vector3 objectPos = Camera.main.WorldToScreenPoint (transform.position);
	mousePos.x = mousePos.x - objectPos.x;
	mousePos.y = mousePos.y - objectPos.y;
	
	float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
	transform.rotation = Quaternion.Euler(new Vector3(0, 0,
	                                                  (PlayerRunMovementController.facingRight ? angle : angle )));
}

Thanks for any help you can offer.

Since your player’s x scale just swaps 1 to -1 to look left and right, I believe you can just multiple your angle by your player’s scale to counter it. Does something like this work for you?

float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg * transform.parent.localScale.x;