# Rotate an object smoothly on the Y axis in Unity

I am attempting a simple script to swing a door open in Unity. This requires a smooth rotation of 90 degrees around the Y axis. I have seen that one way to do this is using Unity's Quanternion object. I believed that this should work:

public class DoorOpenScript : MonoBehaviour
{

public float smooth = 20;

// Use this for initialization
void Start ()
{
SwingOpen ();
}

// Update is called once per frame
void Update ()
{

}

void SwingOpen()
{
Quaternion newRotation = new Quaternion(transform.rotation.x,transform.rotation.y,transform.rotation.z,transform.rotation.w);;
newRotation *= Quaternion.Euler(0, 90, 0); // this add a 90 degrees Y rotation
transform.rotation= Quaternion.Slerp(transform.rotation, newRotation,20 * Time.deltaTime);

}

}


However, this just opens the door completely. I have tried playing with the third parameter to Slerp but with no results. What am I doing incorrectly?

Think about what you need to do, open the door over time. It's not going to happen all in one call in the Start function. You'll need to add a little more rotation each frame to rotate the object smoothly. Something like the following will rotate the object from 0 to 90 degrees over time:

void Update () {
SwingOpen();
}

void SwingOpen()
{
Quaternion newRotation = Quaternion.AngleAxis(90, Vector3.up);
transform.rotation= Quaternion.Slerp(transform.rotation, newRotation, .05f);
}


Notice it's using the Update() function instead of Start(). That's because we want to change it a little each frame. Using Slerp you'll notice that the object swings fast at first, then slower until finally reaching its rotation. The last parameter controls that rate of change, with 1 being instantly and 0 being never.

Perhaps this is your intended behavior, if not you can also perform a constant rotation over time with something like the following:

public float rotationDegreesPerSecond = 45f;
public float rotationDegreesAmount = 90f;
private float totalRotation = 0;
// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
//if we haven't reached the desired rotation, swing

if(Mathf.Abs(totalRotation) < Mathf.Abs(rotationDegreesAmount))
SwingOpen();
}

void SwingOpen()
{
float currentAngle = transform.rotation.eulerAngles.y;
transform.rotation =
Quaternion.AngleAxis(currentAngle + (Time.deltaTime * degreesPerSecond), Vector3.up);
totalRotation += Time.deltaTime * degreesPerSecond;
}


In this case, the rotation of the door will take 2 seconds to reach 90 degrees.

And just a tip, setting the variables to public will allow you to edit them from the Unity editor. This means you can apply this same script to multiple objects, but change the values for each object without editing the script.

• Sorry for my confusion, I understand the first part and it works as you describe. However, for the second method you illustrate, why does the line: if(transform.rotation.eulerAngles.y<rotationDegreesAmount) { SwingOpen(); } not prevent the object from rotating after the condition is met?(i.e. after the transform's rotation around the y axis reaches the specified rotation degrees amount)? – Christian Aug 28 '13 at 15:47
• Well, that line is a bit sloppy. It does stop the object from rotating anymore if the rotation is positive. Really you should keep track of the total rotation so far. I'll update it. – MichaelHouse Aug 28 '13 at 15:53
• So that should rotate indefinitely? – Christian Aug 28 '13 at 16:02
• I assumed you wanted it to stop after rotating a certain amount? The current code should rotate the door by 90 degrees and then stop. If you want to rotate it forever, you can remove the check. – MichaelHouse Aug 28 '13 at 16:05
• Yes, thank you that functions how you indicate. I had a typo I believe. Thank you for the informative response. – Christian Aug 28 '13 at 18:32