- Home /
Frame rate independent animation not working with Time.deltaTime or Coroutines
I have a script based animation in C# that uses Quaternion.Slerp(). However, I cannot seem to get it to be frame rate independent no matter what I try.
These are the two methods I've tried which rotate an object based on how much you have moved the mouse. As you can see, if you move the mouse fast to the left/right/up/down, the object would rotate quickly, and then Slerp() would rotate the object back to 0,0,0.
This code is located inside of Update(). Timescale is 1. I test the scene with a frame rate of about 100fps and then 500fps and rotation behaves very differently if I switch between those frame rates.
float rotateX = InputOSP.GetAxis("Mouse Y") * rotateAmount * Time.deltaTime;
float rotateY = InputOSP.GetAxis("Mouse X") * rotateAmount * Time.deltaTime;
Vector3 newRotation = new Vector3(defaultRotation.x - rotateX, defaultRotation.y + rotateY, defaultRotation.z);
currentItem.transform.localRotation = Quaternion.Slerp(currentItem.transform.localRotation, Quaternion.Euler(newRotation), rotateSpeed * Time.deltaTime);
I've also tried a similar method using a Coroutine that is started from Start() and run as an IEnumerator function, but this also is not framerate independent:
while(true){
float rotateX = InputOSP.GetAxis("Mouse Y") * rotateAmount;
float rotateY = InputOSP.GetAxis("Mouse X") * rotateAmount;
Vector3 newRotation = new Vector3(defaultRotation.x - rotateX, defaultRotation.y + rotateY, defaultRotation.z);
currentItem.transform.localRotation = Quaternion.Slerp(currentItem.transform.localRotation, Quaternion.Euler(newRotation), rotateSpeed);
yield return new WaitForSeconds(0.2F);
}
I also desperately tried running it from FixedUpdate() but that also did not give me a framerate independent animation.
Any tips would be greatly appreciated!
Answer by Eric5h5 · Apr 17, 2013 at 09:33 PM
Mouse input is already framerate-independent; never multiply it by Time.deltaTime, because doing so makes it framerate-dependent.
So that means do not multiply anything by Time.deltaTime in the method using Update() if we are using $$anonymous$$ouse Input. Correct? I want to post back confirmation for others who read this answer. It seems to work fairly good but it does still animate differently between the two frame rates. But it's fairly similar.
Also, as a second question, do you have any idea why the Coroutine didn't work? I wasn't multiplying it by time.timeDelta but it still behaved drastically different at different fps.
If you're using mouse input, you shouldn't use Time.deltaTime. For example, if it takes you 1 second to move the mouse 1000 pixels, then you are doing so regardless of the framerate. If you toss Time.deltaTime in there, then you've made the movement rate vary depending on the framerate.
As for the coroutine, is there any reason for using WaitForSeconds? That will result in very choppy movement. Normally you use yield return null to wait a frame.
I was using WaitForSeconds to create my own "frame rate" as per this answers.unity3d question: http://answers.unity3d.com/questions/236480/having-trouble-figuring-out-coroutines-in-c.html. Yes it was a bit choppy for sure but I was curious if it would solve my problem so I wanted to try it. (by the way I know I have WaitForSeconds(0.2F) but it's actually 0.02F).
Your answer
Follow this Question
Related Questions
function behaves unexpectedly inside a coroutine. 2 Answers
Yield Wait for Seconds (A little help here) 2 Answers
Can the animation editor create local rotational data? 3 Answers
Animation method/coroutine playable once or loop 0 Answers
How can I stop a parented object from resetting its transform when a parent animation play? 1 Answer