# LookAt only in Z axis

I'm fairly new to game development, like many of us asking questions here

Currently, I'm trying my luck working on a simple space shooter.

I'm trying to add some enemy ships with movement, they will only move forwards, but, at all time, will be facing the player ship´

I have that figured out, after playing with many options, LookAt was my saviour, but now, I'm having an issue, they do rate to face the player, but they also rotate on the Y axis

This is how they are in the editor looking

This is the position setting

Their properties

Their code

using UnityEngine;

public class AlienMovement : MonoBehaviour {

public GameObject PlayerShip;
public float speed;

// Use this for initialization
void Start () {
GetComponent<Rigidbody> ().velocity = transform.up * speed * -1;
}

// Update is called once per frame
void Update () {
transform.LookAt (PlayerShip.transform, Vector3.up);
}
}


And how they look once the game is running (frame still)

Transform properties for the one on the right

Any idea what I'm doing wrong?

• Do I understand correctly that the "front" of the ship is pointing along its local -y direction? (ie. the green arrow points backward when in local translation mode) – DMGregory Apr 4 '18 at 0:40
• in theory, that's correct, hence why LookAt has Vector3.up, but then again, its getting some rotation that makes the graphics look inclined – CJLopez Apr 4 '18 at 1:32
• Ah, that's not what that parameter means. I'll answer shortly if no one else beats me to it. – DMGregory Apr 4 '18 at 2:35
• The z-coordinate position value of the ships aren't the same. Try setting them to the same value. – Aj_ Apr 4 '18 at 2:49

First, I notice you seem to be working in the XZ plane. This is a slightly unusual choice for a 2D game, and often requires extra rotation like the 90 degree pitch on your enemy ship sprite. If you choose to switch to the 2D physics system later on, it will expect all your gameplay to be in the XY plane.

Next up, LookAt is designed to point the object's local forward vector at the target — that's the blue Z+ arrow. But that axis Unity calls forward isn't the direction your sprite is facing in the visible art, so LookAt is going to spin us the wrong way.

Instead I'd recommend using its cousin, Quaternion.LookRotation. It takes (up to) two parameters:

• first, a direction to point the local Z+ axis

• second, a direction to point the local Y+ axis

So we can use this to steer our local Y in a particular direction while keeping our Z facing us flat into the gameplay plane.

// Since you're looking down on the XZ plane,
// the Y- axis AKA Vector3.Down is your viewing direction.
// You can change this if you decide to change planes later.
Vector3 intoPlane = Vector3.Down;

// Calculate a vector pointing to the target.
Vector3 toTarget = playerShip.transform.position - transform.positition;

// Point our Z+ into the gameplay plane,
// and our Y+ away from the target.
// (Since our "front" is at the bottom/Y- extreme)
transform.rotation = Quaternion.LookRotation(intoPlane, -toTarget);

• Wow, thanks for taking the time and explaining this to me. Yeah, I know it's odd I'm not using 2D for a 2D, it's only that, I'm planning on having a layer mechanic as well, hence why it's in 3D, or well, in this case, a 2.5D. I did try previously using the Quaternion.LookRotation, but did not had much luck with it, so I will give it another try with your suggestion. Thanks – CJLopez Apr 4 '18 at 14:23
• Damn, just tested and worked right away!!!! Thanks you so much! – CJLopez Apr 4 '18 at 17:56

transform.LookAt(Transform target, Vector3 worldUp) makes your transform look towards the target while aligning the transform's up vector with the world up vector. It doesn't care about the forward vector. So even though the transform's up and world up vectors are aligned, the forward vectors aren't since your ship positions seem to have different z-coordinate values.

You can fix this by creating a temporary position variable with the same z-coordinate

void Update () {
Vector3 pos = PlayerShip.transform.position;
pos.z = transform.position.z;
transform.LookAt (pos, Vector3.up);
}

• if @DMGregory suggestion doens't work, I'll try yours. Thanks! – CJLopez Apr 4 '18 at 14:23
• Just tested you code, and seems like I'm having the same issue, just, this time, it's the X axis the one keeping the front look at my ship intead of the Z, and didn't get the desired result. @DMGregory did the trick – CJLopez Apr 4 '18 at 18:00
• I missed the part that you are using the z-axis as the world up as seen in the screen-shot. Well, glad you got it sorted out. – Aj_ Apr 4 '18 at 19:59