Search Unity

"Ease in" broken on reset

Discussion in 'Cinemachine' started by Misscelan, Oct 9, 2020.

  1. Misscelan

    Misscelan

    Joined:
    Mar 8, 2013
    Posts:
    176
    I have this cinematic where I have Ease In set to blend the in game camera with the vcam.

    It always works fine the first time, but if I keep calling it sometimes the blend does not work and cuts directly.
    I went down the rabbit hole and found that the issue was that the UpdateClock, sometimes changing from UpdateClock.Late; to UpdateClock.Fixed on the first frame on the cinematic.

    This clock seems to be updated in the UpdateTracker.c -> OnUpdate:

    Code (CSharp):
    1.  public void OnUpdate(int currentFrame, UpdateClock currentClock, Matrix4x4 pos)
    2.             {
    3.                 if (lastPos == pos)
    4.                     return;
    5.  
    6.                 if (currentClock == UpdateClock.Late)
    7.                     ++numWindowLateUpdateMoves;
    8.                 else if (lastFrameUpdated != currentFrame) // only count 1 per rendered frame
    9.                     ++numWindowFixedUpdateMoves;
    10.                 lastPos = pos;
    11.  
    12.                 UpdateClock choice;
    13.                 /*if (numWindowFixedUpdateMoves > 3 && numWindowLateUpdateMoves < numWindowFixedUpdateMoves / 3)
    14.                     choice = UpdateClock.Fixed;
    15.                 else*/
    16.                     choice =  UpdateClock.Late;
    17.                 if (numWindows == 0)
    18.                     PreferredUpdate = choice;
    19.  
    Commenting the lines above fixes the issue, but I wouldn't like to change that everytime I update cinemachine.
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    Thank you for this post. I'm having some trouble understanding why commenting out that line affects the blend. If anything, it should affect how the camera tracks the target and updates itself. Blends are independent of this.

    Are you using Cinemachine in a nonstandard manner? I'd like to have a little context about your use-case. If possible, a small project that repros this issue would be most helpful.
     
  3. Misscelan

    Misscelan

    Joined:
    Mar 8, 2013
    Posts:
    176
    Hi Gregory, thanks for the reply.

    Changing the UpdateClock has a cascade effect that ultimately affects blending. I have deleted all the info that led me to that but if I remember correctly the change of clock was causing an early exit in:

    CinemachineCore.cs-> UpdateVirtualCamera:
    Code (CSharp):
    1. if (UpdateTracker.GetPreferredUpdate(updateTarget) != updateClock)
    2.     return;   // wrong clock
    I stopped checking cause the further I was doing down the rabbit hole the less understanding I had on the code, ultimately I could not figure out what this line was doing and why it would return different results randomly:
    UpdateTracker.cs -> OnUpdate:
    Code (CSharp):
    1. if (numWindowFixedUpdateMoves > 3 && numWindowLateUpdateMoves < numWindowFixedUpdateMoves / 3)
    Which seems to be the one that from time to time returns Fixed instead of Late.

    I'm not doing anything unusual as far as a I know, just a cinematic with one vcam and one cinemachineshot track with some Ease In values.

    Unfortunately, my project is over 20GB big and cinematics have references to different scripts, and as mentioned originally I cannot reproduce the error consistently. It is a cinematic that can be replayed many times in the game, it seems the first time is launched always blends fine, but sometimes when resetting and relaunching the values of cinematic the clock seems to change and then the camera cuts and seems to go to the latest position the vcam had the last time it was played.
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    I just don't see how the vcam update's clock choice can affect the duration of a blend between 2 vcams. It makes no sense to me.

    A little background. Unity has 2 clocks: the physics clock (FixedUpdate) and the render clock (Update/LateUpdate). If a camera is tracking an object with damping, it has to compute on the same clock as the target is animated on, otherwise there will be judder. That's why you tell the CM Brain what update method to use - so that vcams update on the same clock as the things they track.

    In some projects, there are some objects that are animated by physics (RigidBodies) and others that are animated on the render clock in Update or LateUpdate (by animated, I mean that their transforms change - which is all the cameras care about). The SmartUpdate setting on the Brain attempts to detect which clock each target objects are animated on, and update any vcams tracking them on the appropriate clock. That's what UpdateTracker is for. It's a compromise solution for heterogeneous environments. It would be better if all the targets animated consistently on the same clock, but there is nothing Cinemachine can do about that.

    If UpdateTracker is changing its mind about some object, it's because the object is not being animated consistently on the same clock. Sometimes the transform is being moved in FixedUpdate, and sometimes in Update or LateUpdate. That makes trouble for vcams trying to track it. The effect of this would be that there might be some camera judder momentarily until the update tracker settles on the actual current update situation for the object. Blends between vcams won't be affected by this.

    Your hack in Cinemachine is likely hiding a deeper problem in the way you are animating your objects. Without more details about your project it's difficult to say more.