Learning how to program in Unity, so bare with me. I'm making a game called Flappy Bird and I'm having issues with my z-rotation boundaries. Let's say I have some gameObject (call it Bird) that goes up and falls down from the y-axis. However, I want this bird, when it goes down, the z-axis rotates clockwise (so negative rotation). Once it starts falling down, the z-values in the rotation ramps from 0 to -90 in float values. Now, my bird should not keep spinning but stay fixed to the limit until I start flying again. When I make my fly action, the bird should reset the z-rotation back to 0 in a gradual manner, not -45 to 0 immediately.

From what I have achieved, there was no luck for me to stop the spin on the bird. It is just continuously spinning without stopping from the range I want. My range is from 0 to -45 z-axis rotation.enter image description hereenter image description here

I have tried to play around with the transformation of my z values to get an idea, but nada. From what I have gathered and tried, I was playing around with the eulerAngles values, Rigidbody.freezeRotation(), transform.Rotate() method, and even the Quanterion.Euler() method.

here is the code function example I'm making:

public float zTest;
public Vector3 movementDirection;

private void FallSpeed()
    movementDirection.y +=  my_gravity * Time.deltaTime; //my_gravity is set to -9.81f
    transform.position += movementDirection * Time.deltaTime;
    zTest += 1 * movemenntDirection.y;
    transform.rotation = Quaternion.Euler(0, 0, zTest);
    if ((transform.rotation.z >= -45.0f && transform.rotation.z <= 0.0f))
        transform.Rotate(0, 0, zTest); //I have a feeling this is completely bad, but I was trying to reset my rotation values.
        // transform.rotation = Quaternion.Euler(0, 0, zTest); //Another way I was trying it
        // currentEuler = new Vector3(transform.rotation.x, transform.rotation.y, -69); //Another way I was trying it

To be honest, a lot of reading documentation made me more confused in how this interaction is happening and I'm not fully thinking straight at this point. Anyone has suggestions in tackling this problem or pointing me to the right direction? If anything, I will make more edits if needed for clarification and documentation for myself and others.

  • \$\begingroup\$ Do you have a rigidbody on this bird? Transform.Rotate says "rotate by this amount" not "to this angle", so it alone can be responsible for the spinning. So can movementDirection.y increasing without bound. But you can also get spinning if you have a rigidbody that's not set to freeze rotation, so any angular momentum you pick up from clipping a collider gets conserved like you're tumbling through space. \$\endgroup\$
    – DMGregory
    Commented Oct 23, 2022 at 16:21
  • \$\begingroup\$ My bird has rigidbody yes. I see, so you are saying that rotating is completely different than by angle rotation, correct? In my mind, I thought they were pretty similar to each other because they share same concepts, but different uses. \$\endgroup\$ Commented Oct 23, 2022 at 20:20

1 Answer 1


transform.rotation is a unit quaternion, not a triplet of angles in degrees. That means all its components are in the range -1...1. So checking to see if transform.rotation.z >= -45 is meaningless.

Try something like this:

// "movementDirection" is not just a direction, it also has a varying magnitude, 
// so use the conventional name for that: velocity.
public Vector3 velocity;
float _angle;

public float minAngle = -45f;
public float maxAngle = 0f;

private void FallSpeed()
    velocity.y +=  my_gravity * Time.deltaTime;
    // I assume this is intended to apply both y AND x movement?
    transform.position += velocity * Time.deltaTime;

    // Convert velocity to an angle. (If velocity.x is 0, use 1 instead)
    float newAngle = Mathf.Atan2(velocity.y, velocity.x);

    // Convert to degrees, and clamp between your desired range.
    newAngle = Mathf.Clamp(newAngle * Mathf.Rad2Deg, minAngle, maxAngle);

    // Blend from your old angle toward the new angle, smoothly.
    _angle = Mathf.Lerp(_angle, newAngle, Time.deltaTime);

    // Set your rotation to this angle.
    transform.localEulerAngles = new Vector3(0, 0, _angle);
  • \$\begingroup\$ Coming in clutch. This helped me out because I was thinking it through like this, but not as code. However, I have a few questions to understand this better. Basically, when I run this without Lerping the new angle, I get better results. So I scratch it off because it was taking too long to reach to -45.0f. It climbs pretty quick and then it get slowers (which is how the lerp works). Now, I have two questions in regards of this response: 1) Is there a way be gradually faster with lerp than without lerp? 2) without lerp and running this, I'm starting my object with a -20 z-axis rotation, why? \$\endgroup\$ Commented Oct 23, 2022 at 20:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .