- Home /
Camera Jitter / Stutter
Hi!
Is it possible to use Rigidbody.MovePosition instead of velocity to move a character followed by the camera without any stutter / choppiness? I've been searching for days :-(
Exactly the same problem as here:
Enabling 'interpolate' fix half of the stutter: 'While interpolation, horizontal translation in FixedUpdate and LateUpdate completely fixes the jitter on y axis, both on player and the scene, they introduce jitter on the x axis. '
Setting the velocity fix the problem but this is discouraged because it may break the physic, so i'd prefer avoiding it. http://docs.unity3d.com/ScriptReference/Rigidbody-velocity.html
The project is 3d platformer, with lot of fast movement, run, jump, so stutter is really important.
Thanks! This forum is a really strong help.
Thanks alexi but the camera already moves in LateUpdate, no parenting. As said above it's the same situation as here: http://answers.unity3d.com/questions/931654/synchronise-translation-with-physics.html#comment-1012178
The camera LookAt the player, but even when slerping the rotation or lerping the position to have smooth movement, either the player or the background slightly stutter (this is more visible in fullscreen resolution).
Is your camera following behind your player and angled slightly downwards?
Both back tracking and free mode were tested. Yes camera height > player position.
Post the code that deals with camera height. The downward angle part of my inquiry was important by the way :P
Answer by alexi123454 · Jul 22, 2015 at 03:04 PM
Instead of parenting the camera directly to the character, why not make the camera interpolate towards the character's position over time? This would smooth out the camera movements and remove the stutter from the visuals.
If you set the lerp speed to be fairly high, then the position of the camera should be pretty similar to before as well.
Answer by meat5000 · Jul 26, 2015 at 07:47 PM
I tried your script and it seems to work fine for me changing LateUpdate to FixedUpdate. The difference between the deltaTime calculated values in the camerascript and the fixedupdate-updated values of the player causes a small oscillation around the maximum distance point, which is basically your object jitter. You can see this when you Debug.Log the distance. In FixedUpdate this value becomes pretty fixed when moving.
If you really really want to use Update() or LateUpdate() you can try this:
Make a timer in FixedUpdate which records the total fixedDeltaTime passed since the code had last run in Update. Use this variable instead of Time.deltaTime in the code and reset the timer when you are done with the data.
This should help sync up the number of steps calculated for the player with the steps moved by the camera.
void Update()
{
Vector3 camForwardZ = transform.forward;
camForwardZ.y = 0.0f;
float currentDistance = Vector3.Distance (transform.position, player.position);
transform.position = transform.position + ((camForwardZ * (currentDistance - distance_max)) * 3f * timer);
transform.position = new Vector3(transform.position.x, transform.position.y + ((player.position.y + height) - transform.position.y)*timer*2f , transform.position.z);
transform.LookAt (player.position);
ResetTimer();
}
float timer = 0.0f;
void ResetTimer()
{
timer = 0.0f;
}
void FixedUpdate()
{
timer += Time.fixedDeltaTime;
}
I tried your script and it seems to work fine for me changing LateUpdate to FixedUpdate
Thanks for your input meat5000. But that's strange, i still got the stutters when using FixedUpdate (tested on two computers, nvidia and ati cards). I tried your script too. Have you checked it doesn't stutter when building the game?
Anyway I got tired of this and i've switched my player physic to Character Controller, moving in update(), loosing the benefits of a rigid body physics, but the camera doesn't stutter now. Looks like it's inherent to the FixedUpdate behaviour.
I made a basic setup, Player script on a cube and camera1 on Camera, of course, with a terrain.
I was able to reduce error in many many ways but only using FixedUpdate ti$$anonymous$$g completely removed all jitter.
To see it visually I used Shift-F on camera or player in scene view and scroll out. You can see all jitter then. Also it was most apparent when you move your player far out to get the camera straight on then move the player back in to the camera. The biggest sign was the very constant figure I get in Debug.Log on Distance from player to camera while moving at full speed (when distance has reached its limit). If there is no jitter that figure will not budge. Any deviation of that figure is an indication of further ti$$anonymous$$g issues.
Tried Standalone. No jitter.
What are your framerates, FixedTimeStep and $$anonymous$$axAllowedTimeStep values? Do you have a heavy physics routine? If you turn iteration count to 1 (temporarily!) does the jitter go away?
Put a little Debug.Log("I$$anonymous$$ FIRING!!") in Update and a slightly different one in FixedUpdate and see how many FU's you get per U.
I made a basic setup, Player script on a cube and camera1 on Camera, of course, with a terrain.
Same here, with a few colored cubes in the background for a better visualisation of the jitter.
The physics and time parameters are the defaults ones: Sleep: 0.005 Default contact offset: 0.01 Solver iter: 6 (no difference if set it to 1)
Fixed timestep: 0.02 $$anonymous$$aximum allowed: 0.333 Time scale: 1
FPS: 90 average, but it's strange i've seen it ten time higher before (edit: hum maybe because i'm testing on an old ati card right now, my other nvidia card is stronger)
Put a little Debug.Log("I$$anonymous$$ FIRING!!") in Update and a slightly different one in FixedUpdate and see how many FU's you get per U.
I'm not sure to understand what you mean here, but after a few seconds i get 335 log in FU and 392 in U.
That looks the same as my firing rates.
I built for android. It doesnt stutter but movement doesnt look very clean.
Also I notice that the camera likes to glitch out when crossing 90 degree points. You can occasionally see this in editor. I think its because of the line
transform.position = transform.position + ((camForwardZ * (currentDistance - distance_max)) * 3f * timer);
with the way the distance is handled.
If you have added other code to the scripts experiment with moving timer += Time.fixedDeltaTime; around the function (start or end) and try the Reset() call at different points (immediately after data usage or at the end of Update) etc.
Holy crap, this actually fixed my problem! Thanks so much!
Just to be clear, the stutter happens when you are updating the "target" in fixed update and updating the camera in update. Fixed update happens at fixed intervals, update does not. The fix is to change your camera follow update method to be the same as your targets update method.