Having trouble using Vector2.SignedAngle

Hey guys,

I’m working on a top down 2D space sim, and I need a way to calculate the ship’s heading. I would normally just use heading = transform.eulerAngles.z;, but in a 2D scene, the Z axis points downwards, so instead of the degrees increasing when the ship turns right, they do the opposite, starting at 359 and decreasing.

So I’m trying a different approach: Vector2.SignedAngle.

The problem is that I can’t get it to work. In a test I’m doing, I have two game objects, one representing the ship and the other representing the direction it is going in, parented to the ship object, so when the ship turns, the reference object moves accordingly to be in the direction the ship is facing.

I have the following code, but I must be doing something wrong, because it returns nothing but zero.

    public Transform player;
    public Transform target;

    void Update()
    {
        Vector2 shipDir = target.position - player.position;
        Vector2 forward = transform.forward;
        float angle = Vector2.SignedAngle(shipDir, forward);
        Debug.Log("heading = " + angle);
    }

The ship object is player, and the reference object is target. If anyone can tell me what I’ve done incorrectly or suggest a better solution to my problem, i would really appreciate it.

I get it, like “never eat shredded wheat” instead of “never wheat shredded eat”… Anyhow, 2D mode is however you want to define it in 2D space. The world z axis can be pointing away from camera or up in your case. So you use the z instead of the y axis, but you can’t get it in the way you are doing it. transform.forward is still going to return (0,0,1) if the z axis of the transform is aligned with the world z direction. Since you are using a Vector2 to save the variable, the reading will still be (0,0) because it will only save the first 2 floats of the Vector3 direction. You need to only work off the x and z plane, but you are only working off the x and y plane at the moment.

Vector3 dir = player.position - target.position;
Vector2 shipDir = new Vector2(dir.x, dir.z); 
Vector2 forward = new Vector2(transform.forward.x, transform.forward.z);
float angle = Vector2.SignedAngle(shipDir, forward);

if(angle == 0.0)
{
       //heading north
}
else if( angle > 0.0 && angle < 90 )
{
//heading north east
}
else if( angle == 90 )
{
//heading east
} 

//etc. etc. etc.

Debug.Log("heading = " + angle);

Hopefully that helps

I figured it out. For anyone who is having the same issue, here is the solution that worked for me:

heading = Mathf.Repeat(-transform.eulerAngles.z, 360f);

Credit goes to EmmaEwert in the Unity Forums for giving me this excellent solution.