Search Unity

  1. Unity 2019.1 beta is now available.
    Dismiss Notice
  2. We're excited to be bringing you the newest Unity features, news, demos, and we've even got some special guests from some of the industry’s most storied franchises. Set a reminder to tune in on YouTube here
    Dismiss Notice
  3. Unity 2018.3 is now released.
    Dismiss Notice

Programatically switch between virtual cameras

Discussion in 'Cinemachine' started by RedactedProfile, Jul 13, 2017.

  1. RedactedProfile

    RedactedProfile

    Joined:
    Mar 7, 2015
    Posts:
    9
    Good day,

    Simple question: I've got some CineMachine virtual cameras setup around my scene. In my C# script I've got a reference to the gameobject that has the CinemachineVirtualCamera component attached to it as so

    Code (CSharp):
    1. if(currentNode.getCamera() != null)
    2.         {
    3.             Debug.Log("Got Camera, lets try switching");
    4.             GameObject cam = currentNode.getCamera();
    5.          
    6.             cam.GetComponent<CinemachineVirtualCamera>().enabled = true; // <-- doesn't work
    7.         }
    Frankly, this is all the built in Scripting example gives me in terms of how to deal with this.

    I do understand that the example is simply disabling it's highest priority camera and thus falling back onto the only other virtual camera in the scene and then re-enabling it, which is neat, but it and the documentation lacks solid examples of how to programatically switch the current active live camera.

    Any ideas?

    -----

    Edit, because I cant seem to delete

    You know when you post something and you immediately find the solution? Yeah, all I had to do was bump up the camera priority and Cinemachine actively switches it out

    yay
     
  2. Adam_Myhill

    Adam_Myhill

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    322
  3. felixIksz

    felixIksz

    Joined:
    Sep 19, 2017
    Posts:
    5
    Hello,
    I've been searching for a solution for some time but I couldn't figure out how to write a working script for my case.

    I would like to have a flexible camera switch code that can be extended depending on different scenarios.
    In some scenes I have set up several cameras on the same node, rendering different layers with different replacement shaders (meaning that it's absolutely necessary for each camera to have their own camera component and CM brain, right? Therefore I can only store them in a common node, which makes it necessary to refer to them as a game object).

    The script I have right now works just fine with traditional Unity cameras (without CM used), but it won't switch between CM cameras. I have attempted several times to write it referring to virtual cameras but it never worked.

    I would highly appreciate any tips on the issue, as the CM API is very mysterious to me being a beginner developer.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class FlexibleCameraSwitch : MonoBehaviour {
    6.  
    7.     public GameObject[] cameraList;
    8.     private int currentCamera;
    9. void Start () {
    10.         currentCamera = 0;
    11.         for (int i = 0; i < cameraList.Length; i++){
    12.             cameraList[i].gameObject.SetActive(false);
    13.         }
    14.      
    15.         if (cameraList.Length > 0){
    16.             cameraList[0].gameObject.SetActive (true);
    17.         }
    18.     }
    19.    
    20. void Update () {
    21.         if (Input.GetMouseButtonUp(0)){
    22.             currentCamera ++;
    23.             if (currentCamera < cameraList.Length){
    24.                 cameraList[currentCamera - 1].gameObject.SetActive(false);
    25.                 cameraList[currentCamera].gameObject.SetActive(true);
    26.             }
    27.             else {
    28.                 cameraList[currentCamera - 1].gameObject.SetActive(false);
    29.                 currentCamera = 0;
    30.                 cameraList[currentCamera].gameObject.SetActive(true);
    31.             }
    32.         }
    33.     }
    34. }
    I have set up an example scenario to illustrate the question:
    upload_2018-4-3_11-4-42.png
     
  4. felixIksz

    felixIksz

    Joined:
    Sep 19, 2017
    Posts:
    5
    Never mind, I figured out a solution.
    In case anyone is wondering, I'd like to leave some tips here.

    It works in a linear, looping manner: it switches to the next camera in the list when you click. You should set the priority of the CM virtual cameras from high to low: with the brain camera at the end of the list.

    For instance, say you wanna have 3 cameras in your scene in the following order:
    VirtualCamera A (priority of CamA>priority CamB)
    VirtualCamera B (priority of CamB>priority CamC)
    Brain VirtualCamera C .

    Create as many virtual cameras to the same brain, and as many brains as you want (multiple brain method was already explained elsewhere). Most importantly, the brain should always stay at the bottom of the hierarchy of it's vCam children. Adding Brain and Virtual Cameras should be the last step, as CM brains have a funky way of referring to vCam children when you wanna change it afterwords.

    Here is the code. Cheers!

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class FlexibleCMCameraSwitch : MonoBehaviour {
    6.  
    7.     public GameObject[] cameraList;
    8.     private int currentCamera;
    9. void Start () {
    10.         currentCamera = 0;
    11.         for (int i = 0; i < cameraList.Length; i++){
    12.         }
    13.      
    14.         if (cameraList.Length > 0){
    15.             cameraList[0].gameObject.SetActive (true);
    16.         }
    17.     }
    18.  
    19. void Update () {
    20.         if (Input.GetMouseButtonUp(0)){
    21.             currentCamera ++;
    22.             if (currentCamera < cameraList.Length){
    23.                 cameraList[currentCamera - 1].gameObject.SetActive(false);
    24.                 cameraList[currentCamera].gameObject.SetActive(true);
    25.             }
    26.             else {
    27.                 //cameraList[currentCamera - 1].gameObject.SetActive(false);
    28.                 currentCamera = 0;
    29.                 cameraList[currentCamera].gameObject.SetActive(true);
    30.             }
    31.         }
    32.     }
    33. }
     
    Last edited: Apr 3, 2018
  5. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    2,130
    If you have a vcam parented to a brain, you're doing it wrong. The setup should be something like this:

    GameObject 1:
    - Unity Camera component, layer mask includes Layer A and not Layer B
    - CM Brain component

    Game Object 2:
    - Unity Camera component, layer mask includes Layer B and not Layer A
    - CM Brain component

    Game Object 3:
    - On layer A
    - CM Virtual Camera component

    Game Object 4:
    - On layer A
    - CM Virtual Camera component

    Game Object 5:
    - On layer B
    - CM Virtual Camera component

    ...and so on

    GO1 is a Unity Camera whose transform will be driven by the vcams in GO3 and GO4.
    GO2 is a Unity Camera whose transform will be driven by the vcam in GO5.
    and so on

    They are all separate game objects, not parented to each other.
     
    felixIksz likes this.
  6. qVadro

    qVadro

    Joined:
    May 18, 2017
    Posts:
    18
    How to do smooth transition while switching virtual cameras? Without timeline
     
  7. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    2,130
    Set the default blend on the Brain:

    upload_2019-1-7_11-59-53.png

    When you activate a new vcam, it will blend smoothly.
     
    qVadro likes this.
  8. daxiongmao

    daxiongmao

    Joined:
    Feb 2, 2016
    Posts:
    266
    I also think you can make a virtual camera active by disable then enable it. If it is already enabled.
    When all cameras have same priority.

    Have to do it when teleporting the targets.