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
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
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.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FlexibleCameraSwitch : MonoBehaviour {
public GameObject[] cameraList;
private int currentCamera;
void Start () {
currentCamera = 0;
for (int i = 0; i < cameraList.Length; i++){
cameraList[i].gameObject.SetActive(false);
}
if (cameraList.Length > 0){
cameraList[0].gameObject.SetActive (true);
}
}
void Update () {
if (Input.GetMouseButtonUp(0)){
currentCamera ++;
if (currentCamera < cameraList.Length){
cameraList[currentCamera - 1].gameObject.SetActive(false);
cameraList[currentCamera].gameObject.SetActive(true);
}
else {
cameraList[currentCamera - 1].gameObject.SetActive(false);
currentCamera = 0;
cameraList[currentCamera].gameObject.SetActive(true);
}
}
}
}
I have set up an example scenario to illustrate the question:
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!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FlexibleCMCameraSwitch : MonoBehaviour {
public GameObject[] cameraList;
private int currentCamera;
void Start () {
currentCamera = 0;
for (int i = 0; i < cameraList.Length; i++){
}
if (cameraList.Length > 0){
cameraList[0].gameObject.SetActive (true);
}
}
void Update () {
if (Input.GetMouseButtonUp(0)){
currentCamera ++;
if (currentCamera < cameraList.Length){
cameraList[currentCamera - 1].gameObject.SetActive(false);
cameraList[currentCamera].gameObject.SetActive(true);
}
else {
//cameraList[currentCamera - 1].gameObject.SetActive(false);
currentCamera = 0;
cameraList[currentCamera].gameObject.SetActive(true);
}
}
}
}
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.
using UnityEngine;
using Cinemachine;
public class CinemamachineController : MonoBehaviour
{
[Header("Drag&Drop")]
public GameObject cinemachineVirtualCamera;
void Awake()
{
var Vcam = cinemachineVirtualCamera.GetComponent<CinemachineVirtualCamera>();
if (Vcam == null) Debug.LogError("A component cinemachineVirtualCamera is missing\n");
}
}
Instead of doing public GameObject cinemachineVirtualCamera;, why not do public CinemachineVirtualCamera vcam; ? That way, the inspector would not let you drop a non-CinemachineVirtualCamera object there.
We’re always happy to see Cinemachine tutorials, so thanks for that.
One thing: there is a shortcut you can use instead of the camera switcher class. Set all the virtual cameras to the same priority and call vcam.MoveToTopOfPrioritySubqueue() whenever you want to make a specific vcam the active one. Job done.
Hi there! I’m trying to do the same kind of thing but with virtual cameras that follow the player and have confiners. The cameras are switching nicely but the box colliders are being removed from their slots in the confiner as soon as I hit play and then come back when I go back to editing. Any idea what could be causing this? I’ve set up my camera switching script on colliders for each of the rooms and to switch the camera I’m using vcam.MoveToTopOfPrioritySubqueue().