- Home /
Make Quaternion Slerp happen over a 1 second period
Basically, I want my character to Slerp his y axis 90 degrees when the "B" button is being held. When "B" is held, it runs the method "TurnArround()," and "TurnArround()" runs as long as the "B" button is held. I want the rotation to occur over a 1 second period. I have tried so many different variations with Time.deltaTime to try to get this transition to work, but no luck. Also whenever trying these variations, for some reason my character doesn't perform any rotation. The only time I get a visible result of my desired rotation is when I make the time perameter = to 1, but the result is an instant rotation, not over a 1 second period. Can someone plese help me with this? I've been stuck for hours.
Answer by Sonky108 · Sep 17, 2018 at 07:11 AM
Hey! It's better to put code as code, not as image :)
private float rotationTime = 1f;
Quaternion targetRotation;
Quaternion startRotation;
void StartRotation()
{
targetRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y + 90, transform.rotation.eulerAngles.z);
startRotation = transform.rotation;
startTime = Time.time;
currentTime = startTime;
}
void DuringRotation()
{
currentTime += Time.deltaTime;
transform.rotation = Quaternion.Slerp(startRotation, targetRotation, (currentTime - startTime) / rotationTime);
}
You can try something like this. StartRotation when button is pressed and DuringRotation until button is held down :)
I don't know what you mean by... "StartRotation when button is pressed and DuringRotation until button is held down."
In my game you hold down the B button and it should make the character lerp 90 degrees. So I don't know what you mean by when button is pressed. In my game the button is just held down. Not just pressed.
Hey, every button is meant to be pressed :p kidding. What I meant is you can see within Unity three states of a button: pressed, held down, released. Both pressed and released last only one frame, that are states where user starts to held down a button and is about to release it. There are three methods for this:
Input.GetButton(string);
Input.GetButtonDown(string);
Input.GetButtonUp(string);
So, you have GetButtonDown == true during one frame, GetButton is true until user release the button, and then GetButtonUp == true for one frame. After that all of them are false until next input. Check the link below:
https://docs.unity3d.com/ScriptReference/Input.html
In that example you should fire StartRotation when GetButtonDown is true and fire DuringRotation while GetButton is true :)
Answer by Legend_Bacon · Sep 17, 2018 at 02:38 PM
Hello there,
This function here might help you. All you have to do is call RotateOverTime() and pass it:
• The object you want to rotate
• The rotation total duration
• The start rotation (usually just the object's current rotation)
• The target rotation
private void RotateOverTime(GameObject targetObject, float transitionDuration, Quaternion start, Quaternion target)
{
StartCoroutine(RotateOverTimeCoroutine(targetObject, transitionDuration, start, target));
}
private IEnumerator RotateOverTimeCoroutine(GameObject targetObject, float transitionDuration, Quaternion start, Quaternion target)
{
float timer = 0.0f;
while (timer < transitionDuration)
{
timer += Time.deltaTime;
float t = timer / transitionDuration;
t = t * t * t * (t * (6f * t - 15f) + 10f);
targetObject.transform.rotation = Quaternion.Slerp(start, target, t);
yield return null;
}
yield return null;
}
}
I threw in a smoothing functionality, but if you want it to be linear you can throw it away. For more info on that, you can take a look at this page here.
Hope that helps!
Cheers,
~LegendBacon
Answer by LCStark · Sep 17, 2018 at 03:23 PM
You're confusing Quaternion.Slerp
with Quaternion.RotateTowards
. The latter method is the one you are looking for.
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, Time.deltaTime);
EDIT
The third parameter is the rotation step - it limits by how many degrees the rotation should change at a single step, so using just Time.deltaTime
might make the rotation too slow. If you want to rotate by 90 degrees over 1 second, use Time.deltaTime * 90.0f
.