Rigidbody2D not facing in the direction of movement.

Hello,
I tried to make my player face in the direction of movement.
I have looked at a lot of solutions on the internet but no one was working. I tried everything possible but it just dent want to work.

This is my MovePlayer function:

private void MovePlayer(Vector2 InputDirection) {

        
        InputDirection.Normalize();
        rb.velocity = InputDirection * AccelerationSpeed;

        Vector2 moveDirection = rb.velocity;
        if (moveDirection != Vector2.zero) {
            float angle = Mathf.Atan2(moveDirection.y, moveDirection.x) * Mathf.Rad2Deg;
            transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
        }

    }

And this is my Update() function:

Vector2 InputDir = joystick.Direction;
MovePlayer(InputDir);

this is my last recourse from where I got my code:

Can someone pls help me?

Have you tried using transform.eulerAngles instead of transform.rotation?

transform.eulerAngles = new Vector3(0, 0, angle);

(Your code for calculating the angle in degrees looks correct to me)

1 Like

Whilst this isn’t your problem, don’t modify the Transform. The Rigidbody2D is in charge of the Transform so use its API as you do for its velocity. Rotation isn’t special and allows you to just bypass it. Note that instantly changing either the position/rotation will mean you’ll likely overlap stuff so the solver will have to then try to move you out of overlap so if you then change it again, it’ll have to do the same again and you’ll get “jittering” as you’re fighting physics.

Look at the Rigidbody2D Scripting docs. You’ll see there’s both a Rigidbody2D.rotation (this will instantly move it to a rotation though) which you can assign the angle directly and a Rigidbody2D.MoveRotation (this will move it in the next simulation step) which also allows you to assign the angle directly or a Quaternion if you wish.

Physics isn’t running per-frame by default so unless you chaneg that, updating stuff per-frame is pointless.

1 Like

Thanks should i put it in FixedUpdate then?

Im sorry but it is still not working.

This is my current code:

private void MovePlayer(Vector2 InputDirection) {

        
        InputDirection.Normalize();
        rb.velocity = InputDirection * AccelerationSpeed;

        Vector2 moveDirection = rb.velocity;
        if (moveDirection != Vector2.zero) {
            float angle = Mathf.Atan2(moveDirection.y, moveDirection.x) * Mathf.Rad2Deg;
            rb.rotation = angle;
        }

       
    }

This doesn’t describe a problem.

Please explain what IS happening against what you expected to happen.

If you’re saying the angle isn’t changing then you’re overwriting the body/transform elsewhere either in a script or in an animation. Byeond that, it’ll be at the angle you set it at.

Have you debugged your code by outputting what yout angle calculation is to the console or attach a debugger? If not, that should always be your first step, not the forums. :slight_smile:

1 Like

Also keep in mind that Arctangent is going to give you an angle of 0 when the direction is straight to the right. If your sprite is not facing right by default, then the rotation may look incorrect.

2 Likes

Very much agreed which is why I believe it’s important for the OP to be clear on what “not working” means.

  • Not Rotating (is that visually in the scene or the Transform rotation not changing)

  • Isn’t Pointing in the “correct” direction with respect to the Sprite/Visuals

  • I have compilation errors (yep, this happens a lot)

Many an hour has been spent on these forums helping fix a problem without knowing what the actual problem is!

1 Like

Thanks its working now, the problem was that I had an animation controller on my player object

1 Like

Sorry for bothering you again, but do you know how to make the rotation smooth(I’m controlling the player with a touch joystick)?

The player is only rotating at following angles:
0, 45, 90, 135, 180, -45, -90, -135, -180

My code:

private void MovePlayer(Vector2 InputDirection) {

       
        InputDirection.Normalize();
        rb.velocity = InputDirection * AccelerationSpeed;

        Vector2 moveDirection = rb.velocity;
      
        if (moveDirection != Vector2.zero) {
            float angle = Mathf.Atan2(moveDirection.y, moveDirection.x) * Mathf.Rad2Deg;
            Debug.Log(angle);
            rb.rotation = angle - 90f;
        }
      


      
    }

Always start by debugging it yourself i.e. output the values you’re reading from your input and writing into InputDirection. We cannot debug it from here. :slight_smile:

That’s the only thing constraining it.

1 Like

Note that you don’t need to do this adjustment. You can change the rotation direction and zero-degree point by transposing X/Y and/or negating them.

For instance, “Mathf.Atan2(-d.x, d.y)” give -90 degree for Vector2.right and 0 degree for Vector2.up.

1 Like

Thanks everything is working fine now, it was an issue with the Joystick

1 Like