Rotating a 2D sprite to face a target on a single axis.

Yes, yet another one of THESE questions. I know this has been asked numerous times before, but after scouring the board for days I can’t find a solution.

My game is a top-down space shooter, I’m working in the 2D mode in unity (on the XY plane).

Basically when the player comes within a certain range of an enemy I’d like the enemy to turn and face the player. I’m using a circle collider w/trigger to do the detection and capture the target transform (the player’s transform). That part works.

The issue (as always) is that the enemy will not turn around the Z-axis only when it turns. It rotates on all axis and usually ends up with the underside of the enemy sprite “facing” the player. When looking at it in 2D mode you end up looking at the edge of the sprite and it disappears.

Here is the code i’m using:

targetTransform = the player’s transform

transform = the enemy’s transform

Vector3 vectorToTarget = targetTransform.position - transform.position;

transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(vectorToTarget,Vector3.forward), 1 * Time.deltaTime);

Here is the log output in a typical run.

TARGETPOS:(1.1, 1.4, 0.0)
SELFPOS:(5.0, 5.0, 0.0)
VECTOR:(-3.9, -3.6, 0.0)

All those look correct to me. I have a feeling the issue lies in how the rotation is being done.

Some solutions I have seen involve modifying the x or y components of the Quaternion that returns from Quaternion.LookRotation. While that does sort of work, I’ve also read numerous things that say to never modify the components on a Quaternion in that way.


I am sort of lost here. Should I not be using Quaternions to do rotation in 2D? I’m also wondering if this could be caused by the game object being rotated. I’m thinking that possibly LookRotation is not sure what the front of the ship is. In the documentation for LookRotation there is this section:

Returns the computed quaternion. If used to orient a Transform, the Z axis will be aligned with forward and the Y axis with upwards if these vectors are orthogonal.

I’m not quite sure what they are saying here. Does this mean that LookRotation always assumes that Z is forward? How would that ever work in 2D mode?

Any suggestions/help would be appreciated.

I can use :

transform.LookAt(transform.position + new Vector3(0,0,1), vectorToTarget);

to get it to work, but the rotation is immediate instead of a nice fluid turn over time that Slerp will provide.

Try this:

Vector3 vectorToTarget = targetTransform.position - transform.position;
float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * speed);

You will have to define a ‘speed’ variable or replace it with a constant. If you don’t want the rotation eased, replace ‘Slerp’ with RotateTowards, and adjust ‘speed’.

This is a tank turret code that I’ve created and i hope it helps:

using UnityEngine;
using System.Collections;

public class AISmoothLookAT : MonoBehaviour {
	public Transform target;
	public Transform looker;
	public Transform Xsmoothlooker;
	public Transform Ysmoothlooker;
	public float Xspeed = 2f;
	public float Yspeed = 2f;
	// Use this for initialization
	void Start () {
	// Update is called once per frame
	void Update () {
		looker.LookAt (target);
		float YRotation = looker.eulerAngles.y;
		float XRotation = looker.eulerAngles.x;

		Xsmoothlooker.rotation = Quaternion.Slerp(Xsmoothlooker.rotation , Quaternion.Euler(0 , YRotation, 0), Time.deltaTime * Xspeed);
		Ysmoothlooker.rotation = Quaternion.Slerp(Ysmoothlooker.rotation , Quaternion.Euler(XRotation , YRotation, 0), Time.deltaTime * Yspeed);

One more thing: Don’t make the X rotating turret a child of Y rotating turret.

Hey I have had the same problem and think I have found a way to do this quite simply. I would love your imput as its both a question and an answer. Using quaternions in 2D to follow a rotation. Both question and an Answer. - Unity Answers

I realize how old this, but it comes up high on the search results for this issue.

I’ve found that, the trick to using LookRotation in 2d mode, is to flip your arguments to it.

So: Quaternion.LookRotation(Vector3.forward, vectorToTarget)

Rather than: Quaternion.LookRotation(vectorToTarget, Vector3.forward)