3 Cameras, change priority on button press?

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