Bug - RespondToRotateInput function is causing slow motion

Description : I’ve the RespondToRotateInput defined as below

private void RespondToRotateInput()
{
    rocketShipRigidbody.freezeRotation = true;
    ...
    rocketShipRigidbody.freezeRotation = false;
}

This is causing the slow motion effect, in the below video see how the rocket slowly rotates to ground after falling.

This is because the RespondToRotateInput function is always called from Update() and the freezeRotation is turned on and off every frame.

We should rather add a check as below to prevent it from happening, something like

private void RespondToRotateInput()
{
    if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D))
    {
      rocketShipRigidbody.freezeRotation = true;
      ...
      rocketShipRigidbody.freezeRotation = false;
    }
}

This seems to solve the issue, see below video, check the rotation after falling is now uniform (This check is also required in case of rocketShipRigidbody.angularVelocity = Vector3.zero;)

I was expecting this fix in lecture 71 Spit & Polish.

@ben Any comments?

3 Likes

What an awesome bug report, thanks for the detail.

You’re quite right in your analysis. We were actually going to slow down time to achieve a similar effect, which would have been more correct. In this case this is a “desirable bug”, but that’s pretty unpalatable.

I’ll organise a patch with thanks.

Wow nice catch, I think i accidentally fixed this in my version because it annoyed me that the rocket moved at all on landing so i had an oncollisionenter and so it was froze outside of the update loop.

I’m going to modify the end of the final lecture to end-up with this code

image

Thanks guys

3 Likes

Ah yes this slow motion was annoying! My solution after some googling was to ditch transform.rotate
and apply a rotation to the rigidbody with rigidBody.AddRelativeTorque:

private void RespondToRotateInput()
{
        Rotate_rigidbody();
}
private void Rotate_rigidbody()
{
        xAxis = Input.GetAxis("Horizontal");

        rigidBody.AddRelativeTorque(-Vector3.forward * rcsThrust * Time.deltaTime * xAxis);
        Vector3 angularVelocity = rigidBody.angularVelocity;
        rigidBody.AddRelativeTorque(-angularVelocity * stabilisationThrust);
}

Notice the opposite torque added as a ‘stabilisation thrust’ to prevent to rocket to spin out of control.

That’s nice and clean, and it truly fixes the problem. I just wanted to point out that the code change in the lecture ‘spit & polish’ doesn’t fully fix the problem:

    private void RespondToRotateInput()
    {
        rigidBody.freezeRotation = true; // take manual control of rotation

        float rotationThisFrame = rcsThrust * Time.deltaTime;
        if (Input.GetKey(KeyCode.A))
        {
            transform.Rotate(Vector3.forward * rotationThisFrame);
        }
        else if (Input.GetKey(KeyCode.D))
        {
            transform.Rotate(-Vector3.forward * rotationThisFrame);
        }
    }

While it seems to have fixed it in the lecture video, the ship’s rotation still slows down to a rubbery crawl on high frame rates (I get 1500-2000 fps). I think it might be because the rigidBody.freezeRotation = true; line is placed outside of the if statement, so it still gets triggered on every frame.

When I put that line within the if statement, or use the code that you shared in this thread, the problem gets fixed

    float FrameRotation = RcsRotation * Time.deltaTime;
    rigidBody.freezeRotation = false;

    if(Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
    {
        rigidBody.freezeRotation = true;
        transform.Rotate(Vector3.forward * FrameRotation); 
    }
    else if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
    {
        rigidBody.freezeRotation = true;
        transform.Rotate(-Vector3.forward * FrameRotation);
    }

This fixed the slow motion bug for me

Privacy & Terms