How to rotate a rigidbody with torque around only the XY axes?

I’m trying to rotate a rigidbody, based on mouse movement, using torque. If the mouse moves horizontally, the rigidbody should rotate horizontally (around the Y axis). If the mouse moves vertically, the rigidbody should rotate vertically (around the X axis). The Z axis of the rigidbody should never change (always 0).

I’ve tried doing this in a few different ways, but I can’t figure out the math to get the proper axes to rotate around. The below code works when rotating around the X axis. However, rotating around the Y axis results in the Z rotation changing if the X rotation is not 0. If the X rotation is 0, then the Y rotation works as expected.

Using the local Y (transform.up) also will give the incorrect results as the object will rotate in all directions if the X rotation is not 0.

What would be the proper axis to rotate around for the Y rotation?

public class TestRotater : MonoBehaviour {

     private Rigidbody rb;
     private float rotX;
     private float rotY;
     public float speed = 10;

     void Awake() {
         rb = GetComponent<Rigidbody>();
     }

     void FixedUpdate() {
         rotY = Input.GetAxis("Mouse X") * speed;
         rotX = Input.GetAxis("Mouse Y") * speed;
         rb.AddTorque(transform.right * rotX + Vector3.up * rotY);
     }
}

Your problem is coming from the rb maintaining angular momentum from previous torque applications. The quick and dirty fix for this is to change your code to this:

public class TestRotater : MonoBehaviour
{

    private Rigidbody rb;
    private float rotX;
    private float rotY;
    public float speed = 1f;

    void Awake()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        rb.angularVelocity = Vector3.zero; // <-------------------
        rotY = Input.GetAxis("Mouse X") * speed;
        rotX = Input.GetAxis("Mouse Y") * speed;
        rb.AddTorque(transform.right * rotX + Vector3.up * rotY);
    }
}

Obviously, this means your angular velocity will not be reliably influenced by external physics forces (it will get reset and over-ridden each FixedUpdate). Equally, you should be able to see that if any velocity exists from a previous rotation you are going to have a very tricky time regaining control of the new angular velocity.

1 Like