Search Unity

Question 3 Cameras, change priority on button press?

Discussion in 'Cinemachine' started by snowcult, Jan 23, 2021.

  1. snowcult

    snowcult

    Joined:
    Feb 6, 2014
    Posts:
    295
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    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.
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using Cinemachine;
    4. using System;
    5.  
    6. #if UNITY_EDITOR
    7. using UnityEditor;
    8. using UnityEditorInternal;
    9. #endif
    10.  
    11. public class VcamPrioritizerGUI : MonoBehaviour
    12. {
    13.     [Header("On-Screen GUI")]
    14.     public Vector2 Position = new Vector3(30, 10);
    15.     public float Width = 100;
    16.  
    17.     [Header("Priority Levels")]
    18.     public int LowPriority = 1;
    19.     public int HighPriority = 10;
    20.  
    21.     [Serializable]
    22.     public struct Item
    23.     {
    24.         public CinemachineVirtualCameraBase Vcam;
    25.     }
    26.     [HideInInspector]
    27.     public List<Item> Vcams;
    28.  
    29.     // Display a vcam selector on the Game view
    30.     public void OnGUI()
    31.     {
    32.         var numNodes = Vcams?.Count;
    33.         if (numNodes == 0)
    34.             return;
    35.         var style = GUI.skin.button;
    36.         var pos = Position;
    37.         var size = style.CalcSize(new GUIContent("Button")); size.x = Width;
    38.         const float vSpace = 3.0f;
    39.         var baseColor = GUI.color;
    40.         var liveColor = CinemachineBrain.GetSoloGUIColor();
    41.         for (int i = 0; i < numNodes; ++i)
    42.         {
    43.             var vcam = Vcams[i].Vcam;
    44.             if (vcam != null)
    45.             {
    46.                 GUI.color = CinemachineCore.Instance.IsLive(vcam) ? liveColor : baseColor;
    47.                 if (GUI.Button(new Rect(pos, size), vcam.Name))
    48.                     Prioritize(vcam);
    49.                 pos.y += size.y + vSpace;
    50.             }
    51.         }
    52.         GUI.color = baseColor;
    53.     }
    54.  
    55.     // Prioritize the selected vcam
    56.     void Prioritize(CinemachineVirtualCameraBase vcam)
    57.     {
    58.         for (int i = 0; i < Vcams.Count; ++i)
    59.             if (Vcams[i].Vcam != null)
    60.                 Vcams[i].Vcam.Priority = Vcams[i].Vcam == vcam ? HighPriority : LowPriority;
    61.     }
    62. }
    63.  
    64. // What follows if for drawing the custom inspector
    65.  
    66. #if UNITY_EDITOR
    67. [CustomEditor(typeof(VcamPrioritizerGUI))]
    68. class CmNodePrioritizerGUIEditor : Editor
    69. {
    70.     private ReorderableList m_Nodes;
    71.  
    72.     public override void OnInspectorGUI()
    73.     {
    74.         base.OnInspectorGUI();
    75.         EditorGUILayout.Space();
    76.         if (m_Nodes == null)
    77.             SetupNodeList();
    78.         m_Nodes.DoLayoutList();
    79.         serializedObject.ApplyModifiedProperties();
    80.     }
    81.  
    82.     void SetupNodeList()
    83.     {
    84.         var propertyName = "Vcams";
    85.         m_Nodes = new ReorderableList(serializedObject,
    86.             serializedObject.FindProperty(propertyName), true, true, true, true);
    87.  
    88.         m_Nodes.drawHeaderCallback = (Rect r) =>
    89.         {
    90.             EditorGUI.LabelField(r, propertyName);
    91.         };
    92.  
    93.         m_Nodes.elementHeightCallback = (int index) =>
    94.         {
    95.             SerializedProperty element = m_Nodes.serializedProperty.GetArrayElementAtIndex(index);
    96.             var h = EditorGUI.GetPropertyHeight(element.FindPropertyRelative("Vcam"));
    97.             return h + EditorGUIUtility.standardVerticalSpacing;
    98.         };
    99.  
    100.         m_Nodes.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
    101.         {
    102.             var oldLabelWidth = EditorGUIUtility.labelWidth;
    103.             EditorGUIUtility.labelWidth = 1;
    104.             SerializedProperty element = m_Nodes.serializedProperty.GetArrayElementAtIndex(index);
    105.             var p = element.FindPropertyRelative("Vcam");
    106.             EditorGUI.PropertyField(rect, p, GUIContent.none);
    107.             EditorGUIUtility.labelWidth = oldLabelWidth;
    108.         };
    109.     }
    110. }
    111. #endif
    112.  
     
    snowcult likes this.