Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    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:
    1,733
    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:
    1,733
    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:
    1,733
    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:
    1,733
    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:
    1,733
    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:
    1,733
    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.