Search Unity

FixedUpdate or LateUpdate for camera movement

Discussion in 'Scripting' started by Deleted User, Aug 28, 2019.

Thread Status:
Not open for further replies.
  1. Deleted User

    Deleted User

    Guest

    I have a character that moves with physics.
    Where should I put camera movement code? FixedUpdate or LateUpdate?
     
  2. EdGunther

    EdGunther

    Joined:
    Jun 25, 2018
    Posts:
    183
    That's a good question. Does all your player movement exist in FixedUpdate()?
     
  3. Deleted User

    Deleted User

    Guest

    Yes.
    Since I'm using Character Controller, I'm moving the character in FixedUpdate
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    Under normal circumstances, LateUpdate should be called more often than FixedUpdate.

    If the only thing that could possibly change your camera's desired position occurs in FixedUpdate, then changing its position in LateUpdate is wasted effort, because you'll be setting it to the same position multiple times even when you know the target position cannot have changed. So doing it in FixedUpdate might save some effort.

    However, the amount of effort saved is probably trivial. If repositioning your camera takes a significant fraction of your computational power, you have very likely done something horribly wrong.

    You'd also need to be careful to make sure that the camera position is calculated after everything else in FixedUpdate that might change where you want it to be. And if you ever changed the camera logic to depend on something that gets updated outside of FixedUpdate (e.g. based on the user pressing a button), then having the camera code in FixedUpdate could become a problem.

    I'd say it's probably not worth the complications and you should just put your camera code in LateUpdate.
     
    Dextozz likes this.
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    One caveat to putting camera code in LateUpdate is: Does your camera have smoothed movement? If not, then LateUpdate is great.

    If your camera has smoothed movement, then putting that code in LateUpdate could cause your character to appear jittery. Your character will move a lot, then your camera will move a little for multiple frames, then your character will move a lot again. Looking at the environment the movement will be smooth, but your character will be stuttering like crazy. So if your camera movement is smoothed, it better update in the same cycle as the character does.

    The downside of putting camera code in FixedUpdate is that you effectively limit the apparent framerate of the game to whatever the fixed timestep is (you might render 100 frames per second, but only in 50 of those frames will anything change). Them's the breaks when making a physics based game.
     
    Ri_Ya_, Brother_77, TimPham and 3 others like this.
  6. Deleted User

    Deleted User

    Guest

    I don't think camera movement code will ever be bottleneck of any game.

    It's all about smooth movement.

    I did an experiment with the hope to find the answer to this question. But I couldn't see a difference between update modes.
    Maybe a more complex situation is required?

    This is the experiment code. Mover attached to character controller and Follower attached to camera:
    Code (CSharp):
    1. public enum UpdateMode
    2. {
    3.     Update,
    4.     FixedUpdate,
    5.     LateUpdate
    6. }
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Follower : MonoBehaviour
    4. {
    5.     public UpdateMode Mode;
    6.     public Transform Target;
    7.     public Vector3 Offset;
    8.  
    9.     private void FixedUpdate()
    10.     {
    11.         if (Mode == UpdateMode.FixedUpdate)
    12.         {
    13.             Follow();
    14.         }
    15.     }
    16.  
    17.     private void Update()
    18.     {
    19.         if (Mode == UpdateMode.Update)
    20.         {
    21.             Follow();
    22.         }
    23.     }
    24.  
    25.     private void LateUpdate()
    26.     {
    27.         if (Mode == UpdateMode.LateUpdate)
    28.         {
    29.             Follow();
    30.         }
    31.     }
    32.  
    33.     private void Follow()
    34.     {
    35.         transform.position = Target.position + Offset;
    36.         transform.rotation = Quaternion.LookRotation(-Offset);
    37.     }
    38. }
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Mover : MonoBehaviour
    4. {
    5.     public UpdateMode Mode;
    6.     public float Speed = 15;
    7.  
    8.     private CharacterController controller;
    9.     private Vector3 movementDir;
    10.  
    11.     private void Awake()
    12.     {
    13.         controller = GetComponent<CharacterController>();
    14.     }
    15.  
    16.     private void Update()
    17.     {
    18.         movementDir.x = Input.GetAxisRaw("Horizontal");
    19.         movementDir.z = Input.GetAxisRaw("Vertical");
    20.         movementDir.y = 0;
    21.         movementDir.Normalize();
    22.  
    23.         if (Mode == UpdateMode.Update)
    24.         {
    25.             Move(Time.deltaTime);
    26.         }
    27.     }
    28.  
    29.     private void FixedUpdate()
    30.     {
    31.         if (Mode == UpdateMode.FixedUpdate)
    32.         {
    33.             Move(Time.fixedDeltaTime);
    34.         }
    35.     }
    36.  
    37.     private void LateUpdate()
    38.     {
    39.         if (Mode == UpdateMode.LateUpdate)
    40.         {
    41.             Move(Time.deltaTime);
    42.         }
    43.     }
    44.  
    45.     private void Move(float delta)
    46.     {
    47.         controller.Move(Speed * delta * movementDir);
    48.     }
    49. }
    50.  
     
  7. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    With your code, set Mover to LateUpdate and the camera to FixedUpdate. Now, set Time.fixedDeltaTime to something unusually large, like 0.1f (it's usually 0.02f). You should see jittering. (Obviously this would be a silly configuration)

    If the camera movement were smoothed, you could set the Mover to FixedUpdate and the camera to LateUpdate, and you'd see the jitter. This is a far more common configuration in games with physics-controlled characters.
    Code (csharp):
    1. transform.position = Vector3.MoveToward(transform.position, Target.position + Offset, delta * cameraMoveSpeed);
    One thing about the whole FixedUpdate thing is that UnityEditor is frequently locked at specific framerates when the frame processes fast enough (often multiples of 50), while your standalone build won't be. Changing the fixedDeltaTime in the above scenario will help illuminate timing issues that this might trigger.
     
    Deleted User likes this.
  8. AndBje

    AndBje

    Joined:
    Jun 5, 2016
    Posts:
    16
    I have just been playing around with different top-down cameras and character controllers. If I try to adjust the camera in Update or FixedUpdate, I always ended up with a small but noticeable camera shake. But in LateUpdate the camera movement was always smooth. The best practice I have found is: Collect all input during Update, execute the input in FixedUpdate (if doing physics, otherwise Update works perfectly fine), finally adjust the camera position in LateUpdate.
     
    d1favero likes this.
  9. musharafhassan67

    musharafhassan67

    Joined:
    Feb 18, 2022
    Posts:
    2
    LateUpdate
     
  10. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,440
    (Edit to add: didn't notice right away that this thread was necro'ed by a new poster. Please don't.)

    I see no value in updating anything but physics-dependant things in FixedUpdate. The interval between FixedUpdate is, well, fixed, but the number of FixedUpdate cycles between visual updates is best assumed as variable since the frame rate is usually variable(*). Meanwhile, the whole point of moving a camera is to ensure you have the right view matrix just before sending everything off to be rendered as soon as LateUpdate completes, and there's no value in updating that view matrix multiple times before rendering kicks off. If your camera is a child of something moved by Physics, well, you can't help having some redundant transform math, but you shouldn't invite it.

    Because Updates vary, your update cycle may look like this: FFFFUL(r) FFFUL(r) FFFFUL(r) FFUL(r). The best time for camera positioning is in your Lateupdate immediately before (render).

    FixedUpdate - physics including raycasts
    Update - user input and game logic based on the most recent known state
    LateUpdate - final IK and camera corrections

    (*) Yeah, yeah, you put in herculean efforts to nip all GCs and all your players are running on a realtime OS, so your framerate never ever sags, I'm so happy for you.
     
  11. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,481
    2nd post. 2nd Necro despite being told previously.
     
Thread Status:
Not open for further replies.