How to check whether Main Camera (Cinemachine) is ready?

I am trying to render screen space canvas gameobjects based on world space gameobject’s transform position, basically, overhead HUD.

For clarity, I am not rendering in the Update() loop, I am just trying to render the HUD on Start() with the following intentions.

void Start()
{
   cameraController.OnViewportChangedEvent += OnViewportChanged;
   OnViewportChanged();
}

void OnViewportChanged()
{
    foreach(var icon in iconList)
    { 
       Vector3 screenPos = mainCamera.WorldToScreenPoint(icon.position);
       icon.rectTransform.position = screenPos;
    }
}

The method gets called but the screenPos is not where it is expected.

After everything is loaded, and I raise OnViewportChangedEvent manually, the screenPos is then calculated correctly.

This makes me think that Cinemachine is not ready or the virtual camera has not transitioned fully even after all the Start() has run completely.

Another thing I tried is this, inside my cameraController:

IEnumerator Start()
{
          if(m_cinemachineBrain == null) {
              m_cinemachineBrain = FindObjectOfType<CinemachineBrain>();
          }

          while(m_cinemachineBrain.IsBlending) {
              yield return null;
          }

          OnCameraMovedEvent?.Invoke();
}

Still doesn’t work, screen position calculation is still wrong during the initial start up phase.

Is there anyway I can check when Cinemachine (virtual camera) is ready, before I raise cameraController.OnViewportChangedEvent?

Thanks.

After pulling my hair for a bit, I realized a few quirks about Cinemachine.

  1. Cinemachine has a very low script execution order, under the project settings, and using LateUpdate(). Without any manual intervention, any expectation that changes to the aim and body targets will update main camera’s values, will most likely end up wrong.

  2. Cinemachine hides its events in CinemachineCore static variables. So if you rely on intellisense to look up events on CinemachineBrain, CinemachineVritualCamera, CinemachineTransposer etc. will be futile. See: Cinemachine Brain Events | Cinemachine | 3.1.1

I fixed the issue by adding a listener to CinemachineCore.CameraUpdatedEvent.AddListener(OnCameraUpdated);