Camera Jitter using Fixed or LateUpdate, need it to be smooth in both.

I have a character the camera follows. All his movement code is in FixedUpdate, however there are times when he is on moving platforms that don’t use the physics engine, they are just animated, and I parent the character to the platform.

The problem is, if I put the SmoothDamp on FixedUpdate, it works great for normal physics steps, but then the non-physics movement (like when attached to moving platforms) jitters and looks like trash.

If I move the SmoothDamp to LateUpdate (or Update), the physics movement jitters and looks like trash, but the movement while on the moving platforms looks nice and smooth.

I am assuming this is because they are updated differently within the engine. The moving platforms movement is handled automagically every Update, while the physics movement is handled in discrete increments.

I thought that using LateUpdate would resolve these kinds of issues… but it doesn’t.

I also tried swapping around the script process order, as well as calling the camera movement from within the characters LateUpdate function, nothing seems to work at all.

On the other hand… If I don’t use a SmoothDamp or Slerp / Lerp, the camera looks perfect when I use it in LateUpdate.

Here is my code:

function LateUpdate(){
	wantRotation = target.rotation;
	wantRotation.eulerAngles.x = eulerX;
	transform.rotation = wantRotation;
	wantPosition = target.transform.TransformPoint(positionOffset);
	transform.position.x = Mathf.SmoothDamp(transform.position.x, wantPosition.x, posDampVel.x, Time.deltaTime*7);
	transform.position.z = Mathf.SmoothDamp(transform.position.z, wantPosition.z, posDampVel.z, Time.deltaTime*7);
	transform.position.y = Mathf.SmoothDamp(transform.position.y, wantPosition.y, posDampVel.y, Time.deltaTime*10);	

Any help is more than welcome! :smiley:

Hey Kryptos, when you mentioned the rotation about the x axis, it made me start thinking that perhaps I should try to rotate to face the target differently.

This lead me to realize that the problem was that I was Dampening the camera position in the first place, rather than the offset based on the mouse. I needed the camera to remain in an explicit amount away from the ‘target’, however this wasn’t possible because of the dampening effect, it would rotate to look at the target instantly, then take a bit to catch up to the proper position.

By setting the Euler angles manually, this problem was less apparent.

TL;DR: I had to SmoothDamp the offset, not the camera position itself.

Thanks for the help :smiley:

There is still something not quite right about it… :frowning:

It is mostly working, but when I move the mouse, or spin the character around, it jitters.

Here is my entire script, please let me know if you see anything that could be causing it…

#pragma strict
// thing we are following
public var target:Transform;
// offset from target position
public var targetOffset:Vector3 = Vector3(0.0, 0.0, 0.0);
// orbit around target
public var positionOffset:Vector3 = Vector3(0.0, 0.0, 0.0);
// how much to scale the mouse offset by
public var maxOffsetDistance:Vector2;

// DampVel variable
private var posDampVel:Vector3 = Vector3(0.0, 0.0, 0.0);
// multiplier to use for the mouse offset
private var mouseMulti:Vector2;
// amount we are away from center
private var mouseOffset:Vector3 = Vector3(0.0, 0.0, 0.0);
// the mouse offset we 'want' to get to
private var wantMouseOffset:Vector3 = Vector3(0.0, 0.0, 0.0);
// want position of camera
private var wantPosition:Vector3 = Vector3(0.0, 0.0, 0.0);
private var heightDamp:float = 0.0;

function LateUpdate(){
	mouseOffset.x = (maxOffsetDistance.x/Screen.width)*(Input.mousePosition.x-(Screen.width*0.5));
	mouseOffset.z = (maxOffsetDistance.y/Screen.height)*(Input.mousePosition.y-(Screen.height*0.5));
	wantMouseOffset = Vector3.SmoothDamp(wantMouseOffset, mouseOffset, posDampVel, .3);

	wantPosition = target.transform.TransformPoint(positionOffset+wantMouseOffset);
	wantPosition.y = Mathf.SmoothDamp(transform.position.y, wantPosition.y, heightDamp, .5);

	transform.position = wantPosition;
	transform.rotation = Quaternion.Euler(transform.eulerAngles.x, target.transform.eulerAngles.y, transform.eulerAngles.z);