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?
Answer
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.
No comments:
Post a Comment