Search Unity

ActiveVirtualCamera is null - not sure why?

Discussion in 'Cinemachine' started by TheCelt, Sep 27, 2018.

  1. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    742
    I have one virtual camera in my scene and i have a reference to the cinemachine brain but when i do:

    Code (CSharp):
    1. Debug.Log(_cinemachineBrain.ActiveVirtualCamera);
    It is null, shouldn't this be my one and only virtual camera in the scene and not null ? Confused why this is the case. The virtual camera is working too, it follows my game objects but i can't see to get a reference to the relevant virtual camera.
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Not clear why this should be happening. It should work.
    Is it possible that _cinemachineBrain is null?
    What version of CM?
     
  3. Shinzironine

    Shinzironine

    Joined:
    Nov 30, 2013
    Posts:
    32
    Had similar issue, when there were two Cinemachine Brains present in the scene. One of them was not properly initialized. So, check if there are duplicate brains somewhere in your game.
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    It could be a layer thing. CinemachineBrain will only see those vcams that are on layers not filtered out by the attached Camera's layer mask. Check that.
     
  5. lumbryga

    lumbryga

    Joined:
    Feb 28, 2018
    Posts:
    7
    After upgrading my project from Unity 2018.1 to 2018.3, and also upgrading Cinemachine from the asset store version to the latest version on package manager (2.2.8), my script also begun to return null for the ActiveVirtualCamera field.
    Was working fine before the upgrades, and the camera still follows my character as intended.

    Any insights on how to solve this?
     
    Last edited: Feb 13, 2019
  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Can you give some details about what your script is doing? When is ActiveVirtualCamera being called?
     
  7. lumbryga

    lumbryga

    Joined:
    Feb 28, 2018
    Posts:
    7
    It goes something like this:


    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using Cinemachine;
    4.  
    5. [ExecuteInEditMode]
    6. public class BoxConfinerPerspective : MonoBehaviour
    7. {
    8.     GameObject currentVirtualCam;
    9.     GameObject mainCam;
    10.     CinemachineVirtualCamera currentVirtualCamComponent;
    11.  
    12.     void Awake () {
    13.         mainCam = GameObject.Find("Main Camera");
    14.     }
    15.  
    16.     void Start()
    17.     {
    18.         var cinemachineBrain = mainCam.GetComponent<CinemachineBrain>(); //returns the brain GameObject
    19.         var activeVirtualCamera = cinemachineBrain.ActiveVirtualCamera; //returns null, before returned first camera to be displayed
    20.         currentVirtualCam = activeVirtualCamera.VirtualCameraGameObject; //now returns System.NullReferenceException
    21.  
    22.         currentVirtualCamComponent = currentVirtualCam.GetComponent<CinemachineVirtualCamera>();
    23.         //do things based on currentVirtualCamComponent properties
    24.     }
    25.  
    26.     void Update()
    27.     {
    28.         //do things in editor, while not playing, which depends on properties of currentVirtualCamComponent
    29.     }
    30.  
    31.     void FixedUpdate()
    32.     {
    33.         currentVirtualCam = mainCam.GetComponent<CinemachineBrain>().ActiveVirtualCamera.VirtualCameraGameObject;
    34.      
    35.         currentVirtualCamComponent = currentVirtualCam.GetComponent<CinemachineVirtualCamera>();
    36.         //do other things based on currentVirtualCamComponent properties, while playing
    37.    }
    38. }
    39.  
     
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    If that code worked before, it was by accident. There are no guarantees that a vcam will be active until after the first call to LateUpdate().

    This would be a more robust (and efficient) approach:
    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3.  
    4. [ExecuteInEditMode]
    5. public class BoxConfinerPerspective : MonoBehaviour
    6. {
    7.     GameObject mainCam;
    8.     CinemachineBrain brain;
    9.  
    10.     CinemachineVirtualCamera ActiveVirtualCamera
    11.     {
    12.         get { return brain == null ? null : brain.ActiveVirtualCamera as CinemachineVirtualCamera; }
    13.     }
    14.  
    15.     void Awake () {
    16.         mainCam = GameObject.Find("Main Camera");
    17.     }
    18.  
    19.     void Start()
    20.     {
    21.         brain = mainCam.GetComponent<CinemachineBrain>();
    22.         CinemachineVirtualCamera vcam = ActiveVirtualCamera;
    23.         if (vcam != null)
    24.         {
    25.             //do things based on currentVirtualCamComponent properties... but
    26.             // there is no guarantee that this code executes.
    27.             // Better to put the vcam init stuff elsewhere.
    28.         }
    29.     }
    30.  
    31.     void Update()
    32.     {
    33.         CinemachineVirtualCamera vcam = ActiveVirtualCamera;
    34.         if (vcam != null)
    35.         {
    36.             //do things in editor, while not playing, which depends on properties of vcam
    37.         }
    38.     }
    39.  
    40.     void FixedUpdate()
    41.     {
    42.         CinemachineVirtualCamera vcam = ActiveVirtualCamera;
    43.         if (vcam != null)
    44.         {
    45.             //do other things based on vcam properties, while playing
    46.         }
    47.    }
    48. }
     
  9. lumbryga

    lumbryga

    Joined:
    Feb 28, 2018
    Posts:
    7
    Ok, i changed the initialization from the Start method to the LateUpdate method, and also moved everything that was in the Update to the LateUpdate. Initialization is using a trigger now. This means that for every frame I'm checking if it was initialized with an if-statement, which is not optimal, but also not critical.

    I still get NullReferenceException once, everytime I go into play mode nd everytime I stop it. Still not a problem, though.

    Everything is working again now, thanks!
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Fix those null refs. They are evil.
    Moving to LateUpdate is likely unnecessary.
    A bool check for initialized is just fine.