Camera jitter after change on other one

Hello there,

I read sereval topics with this issue and there was said that this issue was fixed in v2.0 but it happens to me very often. Let me explain how it works:

  • I have simple Cinemachine Virtual Camera with Framing Transposer which is following player.
  • When player triggers collider I change Main Camera to Target Group Cinemachine. Here is example of my code how I change current camera:
 public void SetCamera(float min, float max)
        {
            cineMachineMainCamera.SetActive(false);

            _cinemachineFramingTransposer = cinemachineTargetGroup.GetComponent<CinemachineVirtualCamera>().GetCinemachineComponent<CinemachineFramingTransposer>();
            _cinemachineConfiner = cineMachineTargetGroup.GetComponent<CinemachineConfiner>();

            _cinemachineFramingTransposer.m_MinimumFOV = min;
            _cinemachineFramingTransposer.m_MaximumFOV = max;
            _cinemachineConfiner.m_BoundingShape2D = _trigger.CameraZone();

            cinemachineTargetGroup.SetActive(true);
            _cMGeneralManager.UpdateActiveCamera();
        }

UpdateActiveCamera() is doing this:

_activeCamera = _cinemachineBrain.ActiveVirtualCamera;
            _cinemachineVirtualCamera = _activeCamera.VirtualCameraGameObject.GetComponent<CinemachineVirtualCamera>();

            if (_cinemachineVirtualCamera == null)
                _cinemachineVirtualCamera = _activeCamera.VirtualCameraGameObject.GetComponentInChildren<CinemachineVirtualCamera>();

And after this when I back to my Main Camera everything is just fine but when I enter second trigger my Target Camera goes crazy. FoV is changing immediately e.g. from 45 to 55 without any smoothness.

What am I doing wrong? The way I change the camera on enable/disable is wrong? Thanks for any tips.

I’m a little confused about what exactly you’re doing.

Best practice with Cinemachine is to not modify camera settings. Instead, create multiple virtual cameras and activate/deactivate them as needed.

For example, you can have vcam1 that follows the player, and vcam2 that has your target group, with the confiner and FOV all set up in advance. Initially, vcam1 is active. When you enter the trigger zone, just activate vcam2, nothing more, and you will get a smooth transition. When you leave the trigger zone, deactivate vcam2, and you will get a smooth transition back to vcam1.

You can use the CinemachineTriggerAction script to accomplish this code-free.

So let me understand this and if I’m wrong just correct me.
If I got e.g 10 triggers on scene I should make 10 vcams with Target Group for each trigger I’ve got and just work between this two cameras?

Yup. Tune each vcam the way you like it, and let CM blend there when it activates. An inactive vcam costs nothing.

Can you explain me why I can’t modify Cinemachine in runtime? Can I modify some values or just leave it and make new vcam with settings I want?

I can’t find CinemachineTriggerAction. Is this in new version of Cinemachine?

It’s in the latest version of CM, available on Package Manager. Which version of CM are you using?

You can modify values in the vcam, but don’t expect smooth transitions if you do - unless you make the mods while the vcam is inactive, then transition to it.

I’m using v2.1.10.

Okay, so this is the thing, I’m doing it the way you wrote. I turned off vcam1, modify vcam2 and then I set vcam2 active on scene and smooth transition is fine. Everything goes wrong when player or enemy starts moving. FoV is going crazy.

You’re going to have to give me a little more info, so that I can understand.

vcam1 works fine, right? even when the player moves?
vcam2 is the problem?
transition is fine, but afterwards vcam2 goes crazy when the player moves?
please confirm.

If that is the case, can you post here a picture of the inspector for vcam2, and a picture of the object hierarchy showing:

  • main camera
  • vcam2
  • target(s)

That’s right. I’m using vcam1 for 75% time in game.

This goes like this: vcam1 is active. Player entered an trigger zone. I set new settings like FoV min-max and changed bounding shape 2D according to place. I did it before I enable vcam2 and disable vcam1.
When I fire this first time everything is just fine. I disable vcam2 and enable vcam1 when player left zone. But when he triggers next one, just the same way as first one, vcam2 goes crazy.

Here are my pictures with settings. As you can see there are no targets in CinemachineTargetGroup. I’m adding them in runtime after player entered trigger zone.

3855250--326356--vcam1.JPG
3855250--326359--vcam2.JPG
3855250--326362--tragetgroup.JPG

Thanks. Can you share the script that changes the bounding shape?
Also pleas post a picture of the object hierarchy showing:

  • main camera
  • vcam2
  • target(s)

Here is my AreaTrigger.cs:

        [Header("Camera settings:")]
        [SerializeField] float minFOV;
        [SerializeField] float maxFOV;
        [SerializeField] Collider2D cameraZone;

        private Area _area;

        void Start()
        {
            _area = Area.Instance;
        }

        private void OnTriggerEnter2D(Collider2D collision)
        {
            InitializeArea();
        }

        private void InitializeArea()
        {
            _area.UpdateArea(gameObject);
            _area.SetCamera(minFOV, maxFOV);
        }

Here is my Area.cs:

        [Header("Player:")]
        [SerializeField] float playerWeight = 1f;
        [SerializeField] float playerRadius = 1f;
        [Header("Camera:")]
        [SerializeField] GameObject cMMainCamera;
        [SerializeField] GameObject cMTargetGroup;
        [SerializeField] CinemachineTargetGroup group;

        AreaTrigger _areaTrigger;
        CMGeneralManager _cMGeneralManager;
        CinemachineFramingTransposer _cMFramingTransposer;
        CinemachineConfiner _cMConfiner;

        private List<CinemachineTargetGroup.Target> _targetGroup = new List<CinemachineTargetGroup.Target>();

        #region Area instance
        public static Area Instance { get { return _Instance; } }
        protected static Area _Instance;

        private void Awake()
        {
            if (_Instance == null)
                _Instance = this;
        }
        #endregion

        private void Start()
        {
            _cMGeneralManager = CMGeneralManager.Instance;

            _targetGroup.Add(new CinemachineTargetGroup.Target { target = PlayerMovement.Instance.transform, radius = playerRadius, weight = playerWeight });
            group.m_Targets = _targetGroup.ToArray();
        }

        public void DisableTargetGroupCamera()
        {
           if (_targetGroup.Count > 1)
           {
                _targetGroup.RemoveRange(1, _targetGroup.Count - 1);
                group.m_Targets = _targetGroup.ToArray();
            }

            cMTargetGroup.SetActive(false);
            cMMainCamera.SetActive(true);
            _cMGeneralManager.UpdateActiveCamera();
        }

        public void UpdateArea(GameObject go)
        {
            _areaTrigger = go.GetComponent<AreaTrigger>();
        }

        public void SetCamera(float min, float max)
        {
            if (_cMFramingTransposer == null || _cMConfiner == null)
            {
                _cMFramingTransposer = cMTargetGroup.GetComponent<CinemachineVirtualCamera>().GetCinemachineComponent<CinemachineFramingTransposer>();
                _cMConfiner = cMTargetGroup.GetComponent<CinemachineConfiner>();
            }

            _cMFramingTransposer.m_MinimumFOV = min;
            _cMFramingTransposer.m_MaximumFOV = max;
            _cMConfiner.m_BoundingShape2D = _areaTrigger.CameraZone();

            cMMainCamera.SetActive(false);
            cMTargetGroup.SetActive(true);
            _cMGeneralManager.UpdateActiveCamera();
        }

And I’m uploading a screen with hierarchy in scene.

3858289--326824--hierarchy.jpg

The Confiner, when using a polygon collider as a shape, caches the bounding shape for performance. When you change the shape, you must also invalidate the cache to force it to recalculate. Try adding a call to confiner.InvalidatePathCache() after setting m_BoundingShape2D.

1 Like

Oh god… that’s exactly what I needed! Thank you, Gregoryl, for your time and this helpful tip! Have a nice day. :slight_smile:

1 Like