You are using scale changes (size) of the object with negative value on the X-axis to simulate left-right rotation. I mean, in doing transform.localScale = new Vector3 (-1, 1, 1);
, you simply "flip" (mirror at 180 degrees) the image on that axis. It’s not the best solution in the world, but it works. The problem is that you then want to rotate the object "correctly" (that is, using angular rotation to make it point in the direction of the target). Only that its "flip" on the X axis continues, so that the object spinning and flipping ends up being upside down.
The solution is you don’t flip the object on the X-axis, and just use the angular rotation. To prevent it from turning upside down, you flip on the y-axis only when the rotation makes it turn upside down. This occurs when the object moves up and left, or down and left. That is, only when the angle is greater than 90º (when it moves up and left) or is smaller than 90º (when it moves down and left).
This is because the rotation in Unity is counted from 0º to 360º from the "front" direction of the object, with positive value when rotating counterclockwise and with negative value 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’ve added a deceleration radius, so the Chief moves more elegantly when approaching the target (and don’t jump like a madman when on 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:
Note that the character "blinks" when the Sprite is reversed (i.e., it changes immediately when the "flip" occurs). That’s why I said, this approach works, but it doesn’t really work. To do something more professional, use a transition animation between left and right.