Top down game: rotate quad using direction vector

Hi,
i am developing a top-down game where a player drives a tank. Right now tank is represented by a simple quad. And i am having trouble figuring out how to correctly use Quaternion.LookRotation to rotate a Quad to face the way it is driving. Right now i am using below code that works, but i would like to replace it with Quaternion.LookRotation because below code is very hacky.

    private void FixedUpdate()
    {
        float x = Input.GetAxis(horizontalAxis) * moveSpeed * Time.deltaTime;
        float y = Input.GetAxis(verticalAxis) * moveSpeed * Time.deltaTime;

        if (Mathf.Abs(x) > Mathf.Abs(y))
            y = 0;
        else
            x = 0;

        rigidBody.transform.Translate(x, y, 0, Space.World);

        Vector3 z = new Vector3(x, y, 0);
        if (z.sqrMagnitude > 0.0001)
        {
            // i want to replace all this if with something like transform.rotation = Quaternion.LookRotation(...);
            float rot = 0;

            z.Normalize();
            if (FloatEquals(z.x, -1)) // FloatEquals is helper method to compare float because writing z.x == -1.0 would be a mistake
                rot = 90;
            else if (FloatEquals(z.x, 1))
                rot = -90;
            else if (FloatEquals(z.y, 1))
                rot = 0;
            else if (FloatEquals(z.y, -1))
                rot = 180;

            transform.rotation = Quaternion.Euler(0, 0, rot);
        }
    }

When i try to replace all this hacky code to:

transform.rotation = Quaternion.LookRotation(z, new Vector(0,0,-1));

Rotation seems to be off (quad is rotated incorrectly). Can anyone point me to right direction what i am doing wrong?

First please use code tags, read more here. Its really hard to read the code and most people might just over look the thread.

I am assuming your quad is facing the correct direction but is upside down?

Quaternion.LookRotation(vector) I think uses a vector that is orthogonal tot he forward vector given. If you use Quaternion.LookRotation(Vector3:forward, Vector3:up) it will give you a rotation facing the forward direction and have its up vector be aligned with the up vector given.

In short I think you need to replace

with transform.rotation = Quaternion.LookRotation(z, Vector3.up);
Vector3.up is the up vector relative to the world. If you are moving across a hill you will need to change the up vector to the normal of the hill relative to the quad/tank,

Hope that helps.

Maybe i poorly described the problem. Your proposed solution does not work correctly because when i press any of the arrow keys, in the inspector i see that rotation is not restricted to Z axis. What i expect is if i press left, i would expect rotation in euler to be 0;0;90. But with your provided code it is 0;-90;0. So it is penpendicular to camare and thus quad is invisible.
I am starting to think that LookRotation method is not suitable for this job, maybe i can use some another method to calculate this rotation?

Use regular trigonometry to find the desired z angle, then set your euler rotation accordingly.
Mathf.Atan2 takes your y/x values from your motion 2D vector and returns an angle. Convert it from radians to degrees before assigning eulerAngles.

Thanks! That was it, i was able to reduce code to this:

    private void FixedUpdate()
    {
        float x = Input.GetAxis(horizontalAxis) * moveSpeed * Time.deltaTime;
        float y = Input.GetAxis(verticalAxis) * moveSpeed * Time.deltaTime;

        if (Mathf.Abs(x) > Mathf.Abs(y))
            y = 0;
        else
            x = 0;

        rigidBody.transform.Translate(x, y, 0, Space.World);

        float zAngle = Mathf.Atan2(x, y) * Mathf.Rad2Deg * -1;
        transform.rotation = Quaternion.Euler(0, 0, zAngle);
    }
2 Likes