Search Unity

Jitter on objects following Cinemachine camera

Discussion in 'Cinemachine' started by PanicEnsues, Feb 21, 2018.

  1. PanicEnsues

    PanicEnsues

    Joined:
    Jul 17, 2014
    Posts:
    187
    I have a custom "skybox" mesh that follows around the position of the current active camera. It works fine with my gameplay camera, but when a cinemachine timeline starts, the skybox gets very jittery/jumpy. The problem appears to scale with the distance that the camera is moving per frame.

    It looks like a render-timing mismatch, like my skybox's position is updating in a different stage than the camera; but I've tried Update(), FixedUpdate(), and LateUpdate(), and the problem happens regardless of which I use.

    I also tried forcing my follow script to update after Cinemachine.CinemachineBrain.

    Is there a known solution for this? How can I smoothly follow a Timeline Camera animation?

    Thanks!

    -Scott
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Hey Scott,
    Never seen that problem before. Could you upload a small project showing this so I can take a look?
     
  3. PanicEnsues

    PanicEnsues

    Joined:
    Jul 17, 2014
    Posts:
    187
    Absolutely! I posted a small test case you can grab from here; just load and Play the one scene in the file and you'll (hopefully) see the issue.

    I always see a jump at the start of playback (but not always after looping), and usually one or two more large jitters through the 30-second animation.

    Thanks for looking,

    -Scott
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Thanks for the upload. I was seeing your large jitters until I adjusted the script order to put SimpleFollow after CineachineBrain. To prove that the order was correct I added debug logs when the brain set the Camera's transform, and when the skySphere's transform was set. Order is correct: in LateUpdate: first Camera, then Sphere.

    I'm still getting minor jitters here and there. My feeling is that this is normal, and is being unnaturally-emphasized by the high-contrast of the sky texture.

    As an experiment, I took timeline out of the equation, replacing it with this script on the vcam:
    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3.  
    4. public class AnimatePathPos : MonoBehaviour
    5. {
    6.     public float startPos = 0;
    7.     public float endPos = 3;
    8.     public float cycleTime = 15;
    9.  
    10.     float current;
    11.     CinemachineTrackedDolly dolly;
    12.  
    13.     void Start()
    14.     {
    15.         var vcam = GetComponent<CinemachineVirtualCamera>();
    16.         if (vcam != null)
    17.             dolly = vcam.GetCinemachineComponent<CinemachineTrackedDolly>();
    18.         current = 0;
    19.     }
    20.    
    21.     void LateUpdate()
    22.     {
    23.         if (dolly != null)
    24.         {
    25.             current = current + (Time.deltaTime / cycleTime);
    26.             if (current > 1)
    27.                 current = 0;
    28.  
    29.             float pos = 0.5f - (Mathf.Cos(current * Mathf.PI) / 2);
    30.             pos = startPos + pos * (endPos - startPos);
    31.             dolly.m_PathPosition = pos;
    32.         }
    33.     }
    34. }
    35.  
    It changed nothing, the same minor jitters are there. To narrow it down, I changed the vcam's Aim method to DoNothing. Now the sphere moves with the camera, but camera does not rotate. Then, the jitters entirely disappeared.

    So it seems that the culprit is camera rotation, not sphere displacement.

    Narrowing it down still further, I removed CM and timeline entirely from the equation, and put this script directly on the main camera:

    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3.  
    4. public class AnimatePathPosNoCM : MonoBehaviour
    5. {
    6.     public float startPos = 0;
    7.     public float endPos = 3;
    8.     public float cycleTime = 15;
    9.     public Transform target;
    10.     public CinemachinePathBase path;
    11.  
    12.     float current;
    13.  
    14.     void Start()
    15.     {
    16.         current = 0;
    17.     }
    18.    
    19.     void LateUpdate()
    20.     {
    21.         if (path != null)
    22.         {
    23.             current = current + (Time.deltaTime / cycleTime);
    24.             if (current > 1)
    25.                 current = 0;
    26.  
    27.             float pos = 0.5f - (Mathf.Cos(current * Mathf.PI) / 2);
    28.             pos = startPos + pos * (endPos - startPos);
    29.             transform.position = path.EvaluatePositionAtUnit(
    30.                 pos, CinemachinePathBase.PositionUnits.PathUnits);
    31.  
    32.             if (target != null)
    33.                 transform.rotation = Quaternion.LookRotation(
    34.                     target.position - transform.position);
    35.         }
    36.     }
    37. }
    38.  
    Minor jitters still there. If I take out the LookRotation, then it's perfectly smooth.

    Bottom line: I don't think CM is the problem here.
     
  5. PanicEnsues

    PanicEnsues

    Joined:
    Jul 17, 2014
    Posts:
    187
    Wow, thanks for the in-depth debugging, that's super-helpful! I'm duly embarrassed that I apparently failed to test the LateUpdate/Execute Last combination, but that is definitely the magic sauce that fixes the issue.

    Thanks again,

    -Scott
     
    Gregoryl likes this.