- Home /
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! :D
I don't think that this is a good idea to:
Set the x-value of the eurer angles manually.
Use another value than Time.deltaTime in the SmoothDamp function.
Anyway, LateUpdate is the correct method to deal with the camera position. So I think that your issue lies in the Update/FixedUpdate of the target object.
1. The eulerX just stores the current eulerX of the camera. I guess I could replace:
wantRotation = target.rotation;
wantRotation.eulerAngles.x = eulerX;
transform.rotation = wantRotation;
With:
transform.rotation.eulerAngles.y=target.eulerAngles.y;
Essentially, the camera should follow the target at a set orbit, and distance.
2. $$anonymous$$aybe I am not using it properly then, I'll have to double check the API. From what I understand, you pass in the time you want the damp to happen over. So if I pass in .5, it will dampen over 1/2 a second. If you pass in Time.deltaTime, it will happen very fast, like each update. If you pass in a multiplier like I did, it will happen based on the framerate of the machine, but at a slower rate.
I'll recheck the API now.
Yeah, I was using it wrong. You don't need to multiply the time by Time.deltaTime, you just pass in the time, and it does it for you. The issue still remains though.
Answer by Bunzaga · Nov 13, 2012 at 01:02 AM
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 :D
Answer by Bunzaga · Nov 14, 2012 at 07:48 PM
There is still something not quite right about it... :(
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.LookAt(target.transform.TransformPoint(targetOffset+wantMouseOffset)); transform.rotation = Quaternion.Euler(transform.eulerAngles.x, target.transform.eulerAngles.y, transform.eulerAngles.z); }