DeltaTime bug when blending between vcams

Hi,

I have written a custom camera, which inherits from CinemachineVirtualCameraBase. I implemented the abstract InternalUpdateCameraState method in my own class, using it to update the position/orientation of my camera.

My setup is to have a regular camera, which is always active and has a low priority. We have triggers set up in our environments to detect when the player goes inside a building - at which point I activate the indoor camera (activate its GameObject) and Cinemachine blends appropriately. When the player leaves the trigger, I deactivate the GameObject of the indoor camera, and Cinemachine blends back to the regular camera. The blend when I activate a new camera is perfect, but when I deactivate a camera, the blend is often ugly and jerky. After a considerable amount of poking around, I’ve finally cracked the problem.

Deactivating the indoor camera causes the CinemachineVirtualCameraBase’s OnDisable method to call CinemachineCore.Instance.CameraDestroyed(this), which in turn removes that vcam from the mUpdateStatus dictionary inside the CinemachineCore.

Because the CinemachineBrain wants to blend from the indoor camera to the regular one, it puts them into mCurrentLiveCameras so that both cameras will continue to get updated, even though one of them has been disabled. When the outgoing camera next finds itself being updated by the CinemachineCore.UpdateVirtualCamera method, the CinemachineCore looks for the camera in the mUpdateStatus dictionary, and when it doesn’t find it, it adds it back to the dictionary, creating a new UpdateStatus with default values (lastUpdateFrame and lastFixedUpdateFrame are both 0). Immediately after this, when the Core is calculating the frameDelta on line 299, because the new UpdateStatus is using default values, the frame delta will be equal to Time.frameCount - potentially hundreds of thousands! It then goes on to multiply the deltaTime value by the frameDelta before passing the adjusted deltaTime value into the InternalUpdateCameraState method of the vcam. This is what’s causing my cameras to jump all over the place - they’re being given a deltaTime in the thousands.

I’m not familiar enough with the rest of the Cinemachine codebase to be able to say for certain what the solution to this should be - but would it be a problem to move CinemachineVirtualCameraBase’s call to CinemachineCore.Instance.CameraDestroyed out of OnDisable and into OnDestroy?

What version of Cinemachine are you using?

I’m on 2.5.0

Can you try with 2.6.0-preview.2? You are possibly possibly tripping over a regression that has been fixed.

Yep, that seems to have fixed it. I see you did move the method call into OnDestroy. That’s a nice sanity check for me! :slight_smile:

1 Like