Update:[Cinemachine] Switching between multiple cameras - Questions & Answers - Unity Discussions
StateDrivenCamera is overkill for this job.
All you have to do is to set the vcam’s Priority field. Higher numbers will dominate. As an example, here is a simple script that lets you set up a list of vcams and it displays an on-screen GUI to select the vcam to switch to. The actual work is done in the Prioritize() method.
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
using System;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditorInternal;
#endif
public class VcamPrioritizerGUI : MonoBehaviour
{
[Header("On-Screen GUI")]
public Vector2 Position = new Vector3(30, 10);
public float Width = 100;
[Header("Priority Levels")]
public int LowPriority = 1;
public int HighPriority = 10;
[Serializable]
public struct Item
{
public CinemachineVirtualCameraBase Vcam;
}
[HideInInspector]
public List<Item> Vcams;
// Display a vcam selector on the Game view
public void OnGUI()
{
var numNodes = Vcams?.Count;
if (numNodes == 0)
return;
var style = GUI.skin.button;
var pos = Position;
var size = style.CalcSize(new GUIContent("Button")); size.x = Width;
const float vSpace = 3.0f;
var baseColor = GUI.color;
var liveColor = CinemachineBrain.GetSoloGUIColor();
for (int i = 0; i < numNodes; ++i)
{
var vcam = Vcams[i].Vcam;
if (vcam != null)
{
GUI.color = CinemachineCore.Instance.IsLive(vcam) ? liveColor : baseColor;
if (GUI.Button(new Rect(pos, size), vcam.Name))
Prioritize(vcam);
pos.y += size.y + vSpace;
}
}
GUI.color = baseColor;
}
// Prioritize the selected vcam
void Prioritize(CinemachineVirtualCameraBase vcam)
{
for (int i = 0; i < Vcams.Count; ++i)
if (Vcams[i].Vcam != null)
Vcams[i].Vcam.Priority = Vcams[i].Vcam == vcam ? HighPriority : LowPriority;
}
}
// What follows if for drawing the custom inspector
#if UNITY_EDITOR
[CustomEditor(typeof(VcamPrioritizerGUI))]
class CmNodePrioritizerGUIEditor : Editor
{
private ReorderableList m_Nodes;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
EditorGUILayout.Space();
if (m_Nodes == null)
SetupNodeList();
m_Nodes.DoLayoutList();
serializedObject.ApplyModifiedProperties();
}
void SetupNodeList()
{
var propertyName = "Vcams";
m_Nodes = new ReorderableList(serializedObject,
serializedObject.FindProperty(propertyName), true, true, true, true);
m_Nodes.drawHeaderCallback = (Rect r) =>
{
EditorGUI.LabelField(r, propertyName);
};
m_Nodes.elementHeightCallback = (int index) =>
{
SerializedProperty element = m_Nodes.serializedProperty.GetArrayElementAtIndex(index);
var h = EditorGUI.GetPropertyHeight(element.FindPropertyRelative("Vcam"));
return h + EditorGUIUtility.standardVerticalSpacing;
};
m_Nodes.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
{
var oldLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 1;
SerializedProperty element = m_Nodes.serializedProperty.GetArrayElementAtIndex(index);
var p = element.FindPropertyRelative("Vcam");
EditorGUI.PropertyField(rect, p, GUIContent.none);
EditorGUIUtility.labelWidth = oldLabelWidth;
};
}
}
#endif
1 Like