// This code dynamically discovers eligible classes and builds the menu // data for the various component pipeline stages. void UpdateStaticData() { if (sStageData != null) { return; } sStageData = new StageData[System.Enum.GetValues(typeof(CinemachineCore.Stage)).Length]; var stageTypes = new List <Type> [System.Enum.GetValues(typeof(CinemachineCore.Stage)).Length]; for (int i = 0; i < stageTypes.Length; ++i) { stageTypes[i] = new List <Type>(); } // Get all ICinemachineComponents var allTypes = Cinemachine.Utility.ReflectionHelpers.GetTypesInAllLoadedAssemblies( (Type t) => Array.Exists(t.GetInterfaces(), (i) => i == typeof(ICinemachineComponent))); // Create a temp game object so we can instance behaviours GameObject go = new GameObject("Cinemachine Temp Object"); go.hideFlags = HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor; foreach (Type t in allTypes) { MonoBehaviour b = go.AddComponent(t) as MonoBehaviour; ICinemachineComponent c = b != null ? (ICinemachineComponent)b : null; if (c != null) { CinemachineCore.Stage stage = c.Stage; stageTypes[(int)stage].Add(t); } } GameObject.DestroyImmediate(go); // Create the static lists for (int i = 0; i < stageTypes.Length; ++i) { stageTypes[i].Insert(0, null); // first item is "none" sStageData[i].types = stageTypes[i].ToArray(); string[] names = new string[sStageData[i].types.Length]; for (int n = 0; n < names.Length; ++n) { if (n == 0) { bool useSimple = (i == (int)CinemachineCore.Stage.Aim) || (i == (int)CinemachineCore.Stage.Body); names[n] = (useSimple) ? "Hard constraint" : "none"; } else { names[n] = NicifyName(sStageData[i].types[n].Name); } } sStageData[i].PopupOptions = names; } }
/// <summary>Add a component to the cinemachine pipeline.</summary> public T AddCinemachineComponent <T>() where T : MonoBehaviour { // Get the existing components Transform owner = GetComponentOwner(); ICinemachineComponent[] components = owner.GetComponents <ICinemachineComponent>(); T behaviour = owner.gameObject.AddComponent <T>(); ICinemachineComponent component = (ICinemachineComponent)behaviour; if (component != null && components != null) { // Remove the existing components at that stage CinemachineCore.Stage stage = component.Stage; for (int i = components.Length - 1; i >= 0; --i) { if (components[i].Stage == stage) { DestroyObject(components[i] as MonoBehaviour); components[i] = null; } } } InvalidateComponentPipeline(); return(behaviour); }
void SetPipelineStage(CinemachineCore.Stage stage, Type type) { Undo.SetCurrentGroupName("Cinemachine pipeline change"); // Get the existing components Transform owner = Target.GetComponentOwner(); ICinemachineComponent[] components = owner.GetComponents <ICinemachineComponent>(); if (components == null) { components = new ICinemachineComponent[0]; } // Find an appropriate insertion point int numComponents = components.Length; int insertPoint = 0; for (insertPoint = 0; insertPoint < numComponents; ++insertPoint) { if (components[insertPoint].Stage >= stage) { break; } } // Remove the existing components at that stage for (int i = numComponents - 1; i >= 0; --i) { if (components[i].Stage == stage) { Undo.DestroyObjectImmediate(components[i] as MonoBehaviour); components[i] = null; --numComponents; if (i < insertPoint) { --insertPoint; } } } // Add the new stage if (type != null) { MonoBehaviour b = Undo.AddComponent(owner.gameObject, type) as MonoBehaviour; while (numComponents-- > insertPoint) { UnityEditorInternal.ComponentUtility.MoveComponentDown(b); } } }
UnityEditor.Editor GetEditorForPipelineStage(CinemachineCore.Stage stage) { foreach (UnityEditor.Editor e in m_componentEditors) { if (e != null) { ICinemachineComponent c = e.target as ICinemachineComponent; if (c != null && c.Stage == stage) { return(e); } } } return(null); }