- Home /
Update() vs. FixedUpdate() for object rotation
I'm experiencing an issue where a game object appears to jitter while rotating at constant speed when the camera follows the object. This jitter is only present when updating the object's rotation in FixedUpdate(); moving the rotation code to Update() eliminates the issue entirely.
Here are links to GIFs of the results:
(The white rectangle in the GIFs helps make the jitter more pronounced)
Rotation code in FixedUpdate(), which looks incorrect: https://imgur.com/a/tgbge82
Rotation code in Update(), which looks correct: https://imgur.com/a/aAjthb3
Why is this jitter present? Unity convention is to put this code into FixedUpdate(), because it deals with physics calculations, so I'm seeking an understanding of why I am not able to perform this behavior in FixedUpdate(). Also in keeping with convention, the camera following code is in LateUpdate(), though changing this does not seem to have an effect.
I've tried too many different approaches to enumerate them, but I can't resolve this issue without using Update(). I'm really interested to know why this doesn't work as expected. Below I will attach the only two scripts in the project in their entirety. One is for the camera following behavior, and the other is for the character rotation.
PlayerRotation.cs
using UnityEngine;
public class PlayerRotation : MonoBehaviour {
// Use this script by attaching it to a gameobject
// that game object will rotate clockwise around the up axis
public float spin_speed = 1.0f;
void FixedUpdate () {
Vector3 current_facing = this.transform.forward;
Vector3 relative_target = this.transform.right;
// pick a new direction to face that is some of the way to the right
Vector3 new_facing =
Vector3.Lerp(
current_facing,
relative_target,
spin_speed * Time.fixedDeltaTime
);
// set our direction to to the new facing
this.transform.forward = new_facing;
}
}
CameraFollower.cs
using UnityEngine;
public class CameraFollower : MonoBehaviour {
// Use this script by attaching it to a gameobject with a camera
// and supplying it with a target gameobject to follow
public GameObject target;
public float target_facing_smoothing_factor = 0.84f;
private GameObject ghost_container;
void Start () {
// create a container to be centered on the target
// make this camera a child of that container
// rotating the container will maintain the camera's
// relative offset and facing
ghost_container = new GameObject(this.gameObject.name + " (container)");
ghost_container.transform.parent = this.transform.parent;
this.transform.parent = ghost_container.transform;
}
void LateUpdate () {
// move the camera container to the target's location
ghost_container.transform.position = target.transform.position;
Vector3 current_facing = ghost_container.transform.forward;
Vector3 target_facing = target.transform.forward;
// rotate (some of the way) to the target's facing direction
ghost_container.transform.forward =
Vector3.Slerp(
current_facing,
target_facing,
target_facing_smoothing_factor
);
}
}
Answer by nobizzle · Nov 17, 2019 at 10:51 PM
The answer to the original question, "why is there jittering when rotating using fixed update," was indeed that the renderer was sometimes showing duplicate frames and sometimes not showing a frame for each state the object was in.
The first answer provided (as well as most answers I could find on the topic in researching the issue) stated that FixedUpdate() should be reserved for physics updates, or something similar. This is not correct, or at least rather misleading. Modifying the code above to use "physics" does not solve the jittering, nor does it address the underlying issue.
It is my determination that FixedUpdate() must be used for all calculations which impact the simulation or gameplay if either is to be deterministic and reproducible. The idea that FixedUpdate() is for physics is sort of correct in that, ideally, the physics should behave the same from run to run. The error is in stating that FixedUpdate() is for only physics. If it is necessary to make the simulation as close to deterministic as possible, all updates to the game's state must occur in FixedUpdate(). In fact, that is what FixedUpdate() is for.
To put it simply, this is an understanding of the relationship between FixedUpdate() and Update() that is helpful to me:
FixedUpdate() is for calculations and updates involving the game world's state, and is called at fixed intervals relative to game world time.
Update() is for any behavior which is not dependent on the game world's time. This can be tricky to understand and get right, but the important take away is that anything that happens in Update() will appear to happen non-deterministically ("at random") from the perspective of the game world. This makes it useful for collecting player input, but not for processing it, for example.
These are generalizations and elide all of the "why," but I think this is a more accurate distinction than simply reserving FixedUpdate() for physics.
It should be noted that the code I originally provided already follows these conditions, but it has that unsightly jitter. There is a solution which enables the correct usage of FixedUpdate() (and therefore a deterministic simulation) and eliminates the jitter: build a state interpolator or extrapolator. In fact, doing so is necessary in order to both maintain reproducibility and show smooth motion of objects at a rate higher than the fixed time step of the game world.
Researching this issue proved to be difficult due to this conflation of purpose for FixedUpdate(). To really understand the issue, and to come up with a solution that worked for me, these sources were valuable:
A famous blog post explaining the implementation of a variable refresh rate game engine (which Unity is).
A Unity Forum discussion in which users debate the correct usage of Update(). The initial response is not correct, hence the length of the discussion.
A helpful visualization and Unity implementation of a possible solution to jitter.
Well, I haven't said that FixedUpdate is for physics only. The only thing I said was 'you are not using physics in your code'. The actual physics functions that should be placed in FixedUpdate are those involving Rigidbody component, because those are functions where inertia is involved and in order to make it framerate independent (so a ball won't roll faster the faster frames change) you'd better place the ball's rigidbody related functions into FixedUpdate and set up the ball's rigidbody interpolation property to reduce the jittering caused by the desynhronization between framerate independent rigidbody inertia in FixedUpdate and the framerate dependent camera updates in Update.
Yes, for the first time it might look like everyone here says 'FixedUpdate is for physics, Update is for the rest'. But it's not true. And we are not saying so actually.
However, I'm glad you've made some great research and found the answers you were looking for.
Answer by Ermiq · Nov 14, 2019 at 12:35 PM
Uhm... You don't use physics in your rotation code actually. To use physics you have to attach the Rigidbody
component to the object and use either Rigidbody.AddTorque() or Rigidbody.MoveRotation().
Since you don't use physics in your code, your code doesn't work properly in FixedUpdate()
. Update()
and FixedUpdate()
are fired in their own different times, Update()
call time depends on the framerate while FixedUpdate()
is framerate independent. You change the object rotation in FixedUpdate()
every 0.04 seconds (default FixedUpdate tick time), and your Update()
might be called 2-3 times between the FixedUpdate ticks, or there might be no Update()
calls at all between 2 FixedUpdates. That's why you have this jittering.
@Ermiq $$anonymous$$y initial thoughts were pretty similar to yours, however, that turns out to be incorrect. The first thing to note is that my object here has a collider. Changing the object's rotation could cause a collision, so I still believe it should be performed in FixedUpdate()
.
Even if it were true that a RigidBody
is required to turn this into a physics update, that would imply that adding a RigidBody
to the object would solve the jitter. Adding a RigidBody
does not remove the jitter, and nor does using RigidBody.$$anonymous$$oveRotation()
ins$$anonymous$$d of setting the transform's forward vector (though it was a good suggestion).
Edit: here I originally responded that I don't think the difference in update frequency between Update()
and FixedUpdate()
was enough to cause this type of jitter, but it almost certainly is the cause. $$anonymous$$oving the camera follower code to FixedUpdate()
does actually solve the jitter, which points to the update synchronization as the root of the issue. However, moving the camera code to FixedUpdate()
should not be considered a solution, because the camera has nothing to do with physics and therefore should not need to rely on FixedUpdate()
. Let me know what you think of these points, and if you have any other ideas.
Try to set rigidBody.interpolation
to Interpolate
. That thing is made specifically for a physics based player character movement.
Speaking of the rotation causing collisions. Yes, it does cause the collisions, but the thing is the rotation with transform.rotation
doesn't deal with physics actually. Physics is inertia, bouncing, friction, etc, and simple transform.rotation
doesn't involve any of these physical properties of the body.
Collisions are not physics in Unity, kind of. In Unity physics is when you apply a force to an object and let the physics engine to calculate inertia, friction and other stuff automatically regarding the rigidbody properties of the object.
Your answer
Follow this Question
Related Questions
Making a bubble level (not a game but work tool) 1 Answer
Sometimes the ball isn't moving 0 Answers
FIXED: How can I stop a collider from tunneling? 2 Answers
Player Control. Roller Ball with Cube Acceleration. 1 Answer
Why my sphere fly away? 1 Answer