You are using scale changes (size) of the object with a negative value on the X axis to simulate the rotation in the left-right direction. That is, by doing transform.localScale = new Vector3 (-1, 1, 1);
, you simply "flip" (mirror 180 degrees) the image on that axis. Not the best solution in the world, but it works. The problem is that afterwards you want to rotate the object in the "correct" way (that is, using angular rotation to make it point in the direction of the target). But his "flip" on the X axis continues, so that the object spinning and flipping ends up upside down.
The solution is you do not flip the object on the X axis, and only use the angular rotation. To prevent it from tumbling upside down, you flick on the Y axis only when the spin causes it to flip. This occurs when the object moves up and to the left, or down and to the left. That is, only when the angle is greater than 90º (when it moves up and to the left) or is smaller than 90º (when it moves down and to the left).
This is because the rotation in Unity is counted from 0º to 360º from the "front" direction of the object, with a positive value when rotating counterclockwise and negative when rotating clockwise.
The code below, then, illustrates a possible solution. I removed the animation part because it does not exist in my example. And I added a deceleration beam, so the sprite moves more elegantly as you approach the target (and do not jump like crazy when on the target).
using UnityEngine;
public class Teste: MonoBehaviour
{
public float speed = 5.0f;
public float reductionRadius = 1.0f;
// Update is called once per frame
void Update()
{
// Use GetMouseButton para um efeito continuo. Caso contrário, vc precisará ficar
// clicando para que o personagem se mova (porque GetMouseButtonDown só é True no
// frame em que o mouse foi pressionado! Já GetMouseButton é True enquanto o mouse
// estiver pressionado!).
if(Input.GetMouseButton(0))
{
// Use posições do mundo, funciona melhor
Vector3 target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
// Como o jogo é 2D, vc não precisa de informação no eixo Z
target.z = 0f;
// Rotaciona o personagem em direção ao alvo
var angle = Mathf.Atan2(target.y - transform.position.y, target.x - transform.position.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0, 0, angle);
// Garante que ele não fique "de cabeça pra baixo", flipando o sprite no eixo Y
// se o ângulo de movimento absoluto for maior do que 90 graus (isto é, sem importar
// se ele está indo pra cima ou pra baixo)
if(Mathf.Abs(angle) > 90f)
transform.localScale = new Vector3(1f, -1f, 1f);
else
transform.localScale = new Vector3(1f, 1f, 1f);
// Move o personagem em direção ao alvo (reduzindo a velocidade conforme
// ele se aproxima do alvo, a partir de um raio de redução configurado)
float dist = (target - transform.position).magnitude;
float movement = speed * Time.deltaTime;
if(dist < reductionRadius)
movement *= dist / reductionRadius;
transform.position += (target - transform.position).normalized * movement;
}
}
}
Illustration of working code:
Notethatthecharacter"blinks" when the sprite is reversed (that is, it immediately changes sideways when "flipping" happens). That's why I said: This approach works, but it does not look really good. To do something more professional, use a transition animation between left and right.