Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Camera jitter after change on other one

Discussion in 'Cinemachine' started by Etirps, Nov 4, 2018.

  1. Etirps

    Etirps

    Joined:
    Apr 16, 2018
    Posts:
    14
    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:

    Code (CSharp):
    1.  public void SetCamera(float min, float max)
    2.         {
    3.             cineMachineMainCamera.SetActive(false);
    4.  
    5.             _cinemachineFramingTransposer = cinemachineTargetGroup.GetComponent<CinemachineVirtualCamera>().GetCinemachineComponent<CinemachineFramingTransposer>();
    6.             _cinemachineConfiner = cineMachineTargetGroup.GetComponent<CinemachineConfiner>();
    7.  
    8.             _cinemachineFramingTransposer.m_MinimumFOV = min;
    9.             _cinemachineFramingTransposer.m_MaximumFOV = max;
    10.             _cinemachineConfiner.m_BoundingShape2D = _trigger.CameraZone();
    11.  
    12.             cinemachineTargetGroup.SetActive(true);
    13.             _cMGeneralManager.UpdateActiveCamera();
    14.         }
    UpdateActiveCamera() is doing this:

    Code (CSharp):
    1. _activeCamera = _cinemachineBrain.ActiveVirtualCamera;
    2.             _cinemachineVirtualCamera = _activeCamera.VirtualCameraGameObject.GetComponent<CinemachineVirtualCamera>();
    3.  
    4.             if (_cinemachineVirtualCamera == null)
    5.                 _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.
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,747
    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.
     
  3. Etirps

    Etirps

    Joined:
    Apr 16, 2018
    Posts:
    14
    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?
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,747
    Yup. Tune each vcam the way you like it, and let CM blend there when it activates. An inactive vcam costs nothing.
     
  5. Etirps

    Etirps

    Joined:
    Apr 16, 2018
    Posts:
    14
    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?
     
  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,747
    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.
     
  7. Etirps

    Etirps

    Joined:
    Apr 16, 2018
    Posts:
    14
    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.
     
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,747
    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)
     
  9. Etirps

    Etirps

    Joined:
    Apr 16, 2018
    Posts:
    14
    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.
     

    Attached Files:

  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,747
    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)
     
  11. Etirps

    Etirps

    Joined:
    Apr 16, 2018
    Posts:
    14
    Here is my AreaTrigger.cs:

    Code (CSharp):
    1.  
    2.         [Header("Camera settings:")]
    3.         [SerializeField] float minFOV;
    4.         [SerializeField] float maxFOV;
    5.         [SerializeField] Collider2D cameraZone;
    6.  
    7.         private Area _area;
    8.  
    9.         void Start()
    10.         {
    11.             _area = Area.Instance;
    12.         }
    13.  
    14.         private void OnTriggerEnter2D(Collider2D collision)
    15.         {
    16.             InitializeArea();
    17.         }
    18.  
    19.         private void InitializeArea()
    20.         {
    21.             _area.UpdateArea(gameObject);
    22.             _area.SetCamera(minFOV, maxFOV);
    23.         }
    Here is my Area.cs:

    Code (CSharp):
    1.  
    2.         [Header("Player:")]
    3.         [SerializeField] float playerWeight = 1f;
    4.         [SerializeField] float playerRadius = 1f;
    5.         [Header("Camera:")]
    6.         [SerializeField] GameObject cMMainCamera;
    7.         [SerializeField] GameObject cMTargetGroup;
    8.         [SerializeField] CinemachineTargetGroup group;
    9.  
    10.         AreaTrigger _areaTrigger;
    11.         CMGeneralManager _cMGeneralManager;
    12.         CinemachineFramingTransposer _cMFramingTransposer;
    13.         CinemachineConfiner _cMConfiner;
    14.  
    15.         private List<CinemachineTargetGroup.Target> _targetGroup = new List<CinemachineTargetGroup.Target>();
    16.  
    17.         #region Area instance
    18.         public static Area Instance { get { return _Instance; } }
    19.         protected static Area _Instance;
    20.  
    21.         private void Awake()
    22.         {
    23.             if (_Instance == null)
    24.                 _Instance = this;
    25.         }
    26.         #endregion
    27.  
    28.         private void Start()
    29.         {
    30.             _cMGeneralManager = CMGeneralManager.Instance;
    31.  
    32.             _targetGroup.Add(new CinemachineTargetGroup.Target { target = PlayerMovement.Instance.transform, radius = playerRadius, weight = playerWeight });
    33.             group.m_Targets = _targetGroup.ToArray();
    34.         }
    35.  
    36.         public void DisableTargetGroupCamera()
    37.         {
    38.            if (_targetGroup.Count > 1)
    39.            {
    40.                 _targetGroup.RemoveRange(1, _targetGroup.Count - 1);
    41.                 group.m_Targets = _targetGroup.ToArray();
    42.             }
    43.  
    44.             cMTargetGroup.SetActive(false);
    45.             cMMainCamera.SetActive(true);
    46.             _cMGeneralManager.UpdateActiveCamera();
    47.         }
    48.  
    49.         public void UpdateArea(GameObject go)
    50.         {
    51.             _areaTrigger = go.GetComponent<AreaTrigger>();
    52.         }
    53.  
    54.         public void SetCamera(float min, float max)
    55.         {
    56.             if (_cMFramingTransposer == null || _cMConfiner == null)
    57.             {
    58.                 _cMFramingTransposer = cMTargetGroup.GetComponent<CinemachineVirtualCamera>().GetCinemachineComponent<CinemachineFramingTransposer>();
    59.                 _cMConfiner = cMTargetGroup.GetComponent<CinemachineConfiner>();
    60.             }
    61.  
    62.             _cMFramingTransposer.m_MinimumFOV = min;
    63.             _cMFramingTransposer.m_MaximumFOV = max;
    64.             _cMConfiner.m_BoundingShape2D = _areaTrigger.CameraZone();
    65.  
    66.             cMMainCamera.SetActive(false);
    67.             cMTargetGroup.SetActive(true);
    68.             _cMGeneralManager.UpdateActiveCamera();
    69.         }
    And I'm uploading a screen with hierarchy in scene.
     

    Attached Files:

  12. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,747
    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.
     
    Etirps likes this.
  13. Etirps

    Etirps

    Joined:
    Apr 16, 2018
    Posts:
    14
    Oh god.. that's exactly what I needed! Thank you, Gregoryl, for your time and this helpful tip! Have a nice day. :)
     
    Gregoryl likes this.