- Home /
Interpolating positions between FixedUpdate frames?
Lockstep Framework uses FixedUpdate () in Unity to match an assumed fixed timestep. At higher rates, FixedUpdate doesn't at all run at a fixed rate but instead runs multiple times in a single frame to make up for a skipped interval. Something like this occurs:
In the image, blue ticks represent frames at fixed timesteps, red ticks represent render frames (what I want to interpolate to), and green ticks represent when FixedUpdate frames might actually run. Between the 4th and 3rd to last green ticks, a big gap is present which leads to stuttering with linear interpolation.
How is interpolation done for a simulation running assuming a fixed timestep that runs at an unfixed timestep? I.e. Unity's RigidBodies interpolate very well.
I've never been aware of this, but what are you trying to interpolate? Why don't you use Unity's Linear Interpolation (Lerp)? $$anonymous$$athf.Lerp, Color.Lerp, Vector3.Lerp, what exactly are you wanting to do?
Sorry for not elaborating. It's interpolation between position. Vanilla linear interpolation (lerp) with an accumulator has stuttering because of the uneven distribution of simulation frames.
https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/
you might wanna try this
Hi, I did something similar with some simple custom physics. What I did is compute a nextPhysicsPosition during fixed update but not actually use it for physics behavior. That is, the physics state used by the game is "late" by 1 fixed step (and then next FixedUpdate, set "currentPhysicsPosition" to "nextPhysicsPosition" and compute the next "next" etc...). I also store the current Time.FixedTime in some global lastFixedTime variable.
Then, during Update, I just interpolate from currentPhysicsPosition to NextPhysicsPosition using (Time.time - lastFixedTime)/Time.fixedDeltaTime. It works well when reducing time scale to some very small values to simulate high fps. I guess it's how Unity manages rigidbody interpolation, also buffering next frame collisions events.
One previous comment talks about extrapolation. It should work too but extrapolating values can lead to positions that will be corrected/changed by game events (i.e. player clicking/changing direction etc...).
Also, I've never observed such a big gap between FU and U. I don't think unity would call a U frame with a time greater than the next ideal FU time. In your image, Unity would "realize" that it should call a FU frame ins$$anonymous$$d of a U when the timer is just past the ideal blue tick.
Answer by gresolio · Apr 07, 2016 at 10:43 PM
"Fix Your Timestep!" by Glenn Fiedler is a very good article, it helps to understand the game loop in general. One solution is to interpolate between the previous and current physics state based on how much time is left in the accumulator:
const double alpha = accumulator / dt;
State state = currentState * alpha + previousState * ( 1.0 - alpha );
But unfortunately we don't have direct access to the FixedUpdate's accumulator in Unity. As _dns_ answered earlier, the (Time.time - Time.fixedTime) is the closest value to it:
float alpha = (Time.time - Time.fixedTime) / Time.fixedDeltaTime;
Vector3 lerpState = Vector3.Lerp(previousState, currentState, alpha);
Complete example: Unity_FixedUpdate_Aliasing. Please someone correct me if you know a better way to get the accumulator value from the FixedUpdate loop (it would be nice to look at the source code of Unity, but I don't have such possibility). Recently I've also posted some useful links on the forum (post #71), feel free to read them all :)