Search Unity

Cinemachine not following and looking at target after level load

Discussion in 'Cinemachine' started by tcz8, May 20, 2020.

  1. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    I'm currently working on our game manager and loading levels and I'm having issues getting cinemachine to behave.

    Problem #1
    Right after load, CinemachineBrain and StateDrivenCamera start disabled. I set the Follow and LookAt targets of the StateDrivenCamera and then enable CinemachineBrain followed by the StateDrivenCamera (I tried reversing the order in which these last two are enabled but it didn't change anything).

    At this point the camera works and I have an image on screen but although I can confirm (via the inspector in play mode) that the targets have been set properly, the StateDrivenCamera doesn't look at the right thing. It doesn't seem to realise it has a target set until I disable and re-enable it manually.

    Problem #2
    Cinemachine trows a null ref. error after enabling the StateDrivenCamera (called "cinemachine" in our code).

    Here is a full stack + related source:

    Code (CSharp):
    1. [Exception] NullReferenceException: Object reference not set to an instance of an object
    2. CinemachineFreeLook.set_PreviousStateIsValid()    Library/PackageCache/com.unity.cinemachine@2.5.0/Runtime/Behaviours/CinemachineFreeLook.cs:208
    3. 206:       if (value == false)
    4. 207:           for (int i = 0; m_Rigs != null && i < m_Rigs.Length; ++i)
    5. -->208:               m_Rigs[i].PreviousStateIsValid = value;
    6. 209:       base.PreviousStateIsValid = value;
    7. 210:   }
    8.  
    9. CinemachineVirtualCameraBase.OnEnable()    Library/PackageCache/com.unity.cinemachine@2.5.0/Runtime/Core/CinemachineVirtualCameraBase.cs:354
    10. 352:       UpdateVcamPoolStatus();    // Add to queue
    11. 353:       if (!CinemachineCore.Instance.IsLive(this))
    12. -->354:           PreviousStateIsValid = false;
    13. 355:       CinemachineCore.Instance.CameraAwakened(this);
    14. 356:   }
    15.  
    16. CinemachineFreeLook.OnEnable()    Library/PackageCache/com.unity.cinemachine@2.5.0/Runtime/Behaviours/CinemachineFreeLook.cs:171
    17. 169:   {
    18. 170:       mIsDestroyed = false;
    19. -->171:       base.OnEnable();
    20. 172:       InvalidateRigCache();
    21. 173:   }
    22.  
    23. GameObject.SetActive()
    24.  
    25. GameManager.SetCameraEnabled()    Assets/_Scripts/GameManager/GameManager.cs:456
    26. 454:       //mainCamera.gameObject.SetActive(isEnabled);
    27. 455:       mainCamera.gameObject.SetActive(isEnabled);
    28. -->456:       cinemachine.gameObject.SetActive(isEnabled);
    29. 457:   }
    30.  
    31. GameManager.ConfigureScene()    Assets/_Scripts/GameManager/GameManager.cs:383
    32. 381:       }
    33. 382:       SetCameraTarget(cameraTarget);
    34. -->383:       SetCameraEnabled(true);
    35. 384:   }
    36.  
    37. M7.<LoadSceneAsynchronously>d__48.MoveNext()    Assets/_Scripts/GameManager/GameManager.cs:345
    38. 343:       }
    39. 344:       Debug.Log("Done loading: " + pathToScene);
    40. -->345:       ConfigureScene();
    41. 346:   }
    42.  
    43. SetupCoroutine.InvokeMoveNext()    C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17
    44.  
    FYI we are still on Cinemachine 2.5, been looking at the 2.6 changelog but I'm not sure if any of that relates to this problem.

    Does anyone know what is going on?
    Is there a way to tell a Vcam to refresh its target?
     
    Last edited: May 20, 2020
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    Thanks for the report.

    The null ref exception was fixed in 2.6, but for the other issue, I'm going to need a little more info.
    Would you be willing to put together a small lightweight repro project that demonstrates this problem?
     
  3. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    That is possible but not a simple task. Please let me try to describe what you would find in case something pops in mind. In the meantime I will try upgrading to 2.6 and report back.
    1. On play the first thing done is to load our Preload Scene
    2. The preload scene contains the GameManager object and is set to DontDestroyOnLoad. It has several child objects including the CinemachineBrain and our StateDrivenCamera. Initially, all those child objects are disabled and targets are null.
    3. Then we load the menu scene (has its own camera) from which we chose a level and load it with LoadSceneAsync
    4. The game manager has settings for each game scene which tells it which child objects should be enabled and how to handle them. So once asyncOperation.isDone, in the same coroutine, we enable what's configured for the scene including CinemachineBrain and StateDrivenCamera. Currently, we set the targets just before enabling the camera system. We tried setting the targets after but it didn't change anything. This is the code used:
      Code (CSharp):
      1. // Set Targets
      2. stateDrivenCamera.Follow = target;
      3. stateDrivenCamera.LookAt = target
      4. // Enable Camera System
      5. mainCamera.gameObject.SetActive(true);
      6. stateDrivenCamera.gameObject.SetActive(true);
      7. // Tried with and without this next line
      8. stateDrivenCamera.PreviousStateIsValid = false;
    5. At this point the inspector confirms that the targets are set to the requested object but the camera is not looking at it. When tested with a moving target, it doesn't follow it either.
    6. If I disable and enable the StateDrivenCamera game object manually then the camera orient itself (rather ungracefully) and starts looking at and following the target.
    There is only one CinemachineBrain in the scene, no duplicate cameras, everything else appears to works as intended. The only error I get is the null ref we spoke of earlier.

    I'll get back to you soon.
    Thank you for your help.
     
    Last edited: May 26, 2020
  4. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    Good news! 2.6 fixed the error AND the target problem.

    But there is still a jerk when setting targets. I read we were supposed to blend in from another vcam to avoid this but I'm not sure how to implement this in our setup.

    After scene load, the target is set once to the player's spawnpoint and again, to the player, when he presses a button to spawn. Both cause a camera jerk.

    What's the recommended way to set this up? Should the Player and SpawnPoint both have their own vcam in the prefab to blend away from? Can a smooth blend be acheived in script without having to mess with extra game objects/vcams?

    Thank you.
     
    Last edited: May 26, 2020
  5. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    When a new target is set, this is considered to be a reset, and the vcam will snap to the new desired position without any damping. One way to avoid this is to have a constant target object (perhaps an empty game object included with the prefab) that you can then reposition (or reparent) dynamically from script.
     
  6. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    Excellent idea! Thank you!
     
    Gregoryl likes this.
  7. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,369
    I have the same problem in 2019.4.40f1 and CM 2.9.1.
    Any of the cameras i have, they ara always inactive at Play, no follow/lookat. The only way to make them work is to select them in the hierarchy and hit Live button after play.
    Is there any API to make them active/live through script?
     
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    The CM Brain should activate the highest-priority vcam automatically. However, the CM Brain will ignore any vcams that are not on a layer included in the main camera's Layer mask. Is it possible that your vcams are on such a layer?
     
  9. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,369
    Hi,
    After setting the vcam to the same layer as the brain, it worked. The vcam is now automatically active at runtime.
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    It doesn't have to be the same layer as the camera itself, it just has to be on a layer that the camera can see, i.e. one that is included in the Culling Mask.

    upload_2022-9-7_13-52-26.png