/// <summary> /// Draw the Live status in the inspector, and the Solo button /// </summary> protected void DrawCameraStatusInInspector() { if (Selection.objects.Length > 1) { return; } // Is the camera navel-gazing? CameraState state = Target.State; if (state.HasLookAt && (state.ReferenceLookAt - state.CorrectedPosition).AlmostZero()) { EditorGUILayout.HelpBox( "The camera is positioned on the same point at which it is trying to look.", MessageType.Warning); } // No status and Solo for prefabs if (IsPrefabBase) { return; } // Active status and Solo button Rect rect = EditorGUILayout.GetControlRect(true); Rect rectLabel = new Rect(rect.x, rect.y, EditorGUIUtility.labelWidth, rect.height); rect.width -= rectLabel.width; rect.x += rectLabel.width; Color color = GUI.color; bool isSolo = (CinemachineBrain.SoloCamera == (ICinemachineCamera)Target); if (isSolo) { GUI.color = CinemachineBrain.GetSoloGUIColor(); } bool isLive = CinemachineCore.Instance.IsLive(Target); GUI.enabled = isLive; GUI.Label(rectLabel, isLive ? "Status: Live" : (Target.isActiveAndEnabled ? "Status: Standby" : "Status: Disabled")); GUI.enabled = true; float labelWidth = 0; GUIContent updateText = GUIContent.none; UpdateTracker.UpdateClock updateMode = CinemachineCore.Instance.GetVcamUpdateStatus(Target); if (Application.isPlaying) { updateText = new GUIContent( updateMode == UpdateTracker.UpdateClock.Fixed ? " Fixed Update" : " Late Update"); var textDimensions = GUI.skin.label.CalcSize(updateText); labelWidth = textDimensions.x; } rect.width -= labelWidth; if (GUI.Button(rect, "Solo", "Button")) { isSolo = !isSolo; CinemachineBrain.SoloCamera = isSolo ? Target : null; InspectorUtility.RepaintGameView(); } GUI.color = color; if (isSolo && !Application.isPlaying) { InspectorUtility.RepaintGameView(); } if (labelWidth > 0) { GUI.enabled = false; rect.x += rect.width; rect.width = labelWidth; GUI.Label(rect, updateText); GUI.enabled = true; } }
protected void DrawPipelineInInspector() { UpdateInstanceData(); foreach (CinemachineCore.Stage stage in Enum.GetValues(typeof(CinemachineCore.Stage))) { int index = (int)stage; // Skip pipeline stages that have no implementations if (index < 0 || sStageData[index].PopupOptions.Length <= 1) { continue; } const float indentOffset = 4; GUIStyle stageBoxStyle = GUI.skin.box; EditorGUILayout.BeginVertical(stageBoxStyle); Rect rect = EditorGUILayout.GetControlRect(true); // Don't use PrefixLabel() because it will link the enabled status of field and label GUIContent label = new GUIContent(InspectorUtility.NicifyClassName(stage.ToString())); if (m_stageError[index]) { label.image = EditorGUIUtility.IconContent("console.warnicon.sml").image; } float labelWidth = EditorGUIUtility.labelWidth - (indentOffset + EditorGUI.indentLevel * 15); Rect r = rect; r.width = labelWidth; EditorGUI.LabelField(r, label); r = rect; r.width -= labelWidth; r.x += labelWidth; GUI.enabled = !StageIsLocked(stage); int newSelection = EditorGUI.Popup(r, m_stageState[index], sStageData[index].PopupOptions); GUI.enabled = true; Type type = sStageData[index].types[newSelection]; if (newSelection != m_stageState[index]) { SetPipelineStage(stage, type); if (newSelection != 0) { sStageData[index].IsExpanded = true; } UpdateInstanceData(); // because we changed it return; } if (type != null) { Rect stageRect = new Rect( rect.x - indentOffset, rect.y, rect.width + indentOffset, rect.height); sStageData[index].IsExpanded = EditorGUI.Foldout( stageRect, sStageData[index].IsExpanded, GUIContent.none, true); if (sStageData[index].IsExpanded) { // Make the editor for that stage UnityEditor.Editor e = GetEditorForPipelineStage(stage); if (e != null) { ++EditorGUI.indentLevel; EditorGUILayout.Separator(); e.OnInspectorGUI(); EditorGUILayout.Separator(); --EditorGUI.indentLevel; } } } EditorGUILayout.EndVertical(); } }
AxisState def = new AxisState(); // to access name strings public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label) { float height = EditorGUIUtility.singleLineHeight; rect.height = height; mExpanded = EditorGUI.Foldout(rect, mExpanded, label, true); if (mExpanded) { ++EditorGUI.indentLevel; rect.y += height + vSpace; EditorGUI.PropertyField(rect, property.FindPropertyRelative(() => def.Value)); if (!ValueRangeIsLocked(property)) { rect.y += height + vSpace; InspectorUtility.MultiPropertyOnLine(rect, new GUIContent("Value Range"), new [] { property.FindPropertyRelative(() => def.m_MinValue), property.FindPropertyRelative(() => def.m_MaxValue), property.FindPropertyRelative(() => def.m_Wrap) }, new [] { GUIContent.none, new GUIContent("to "), null }); } rect.y += height + vSpace; InspectorUtility.MultiPropertyOnLine(rect, new GUIContent("Speed"), new [] { property.FindPropertyRelative(() => def.m_MaxSpeed), property.FindPropertyRelative(() => def.m_SpeedMode) }, new [] { GUIContent.none, new GUIContent("as") }); rect.y += height + vSpace; InspectorUtility.MultiPropertyOnLine( rect, null, new [] { property.FindPropertyRelative(() => def.m_AccelTime), property.FindPropertyRelative(() => def.m_DecelTime) }, new [] { GUIContent.none, null }); if (HasRecentering(property)) { var rDef = new AxisState.Recentering(); var recentering = property.FindPropertyRelative(() => def.m_Recentering); rect.y += height + vSpace; InspectorUtility.MultiPropertyOnLine( rect, new GUIContent(recentering.displayName, recentering.tooltip), new [] { recentering.FindPropertyRelative(() => rDef.m_enabled), recentering.FindPropertyRelative(() => rDef.m_WaitTime), recentering.FindPropertyRelative(() => rDef.m_RecenteringTime) }, new [] { new GUIContent(""), new GUIContent("Wait"), new GUIContent("Time") }); } rect.y += height + vSpace; EditorGUI.PropertyField(rect, property.FindPropertyRelative(() => def.m_InputAxisName)); rect.y += height + vSpace; InspectorUtility.MultiPropertyOnLine(rect, null, new [] { property.FindPropertyRelative(() => def.m_InputAxisValue), property.FindPropertyRelative(() => def.m_InvertInput) }, new [] { GUIContent.none, new GUIContent("Invert") }); --EditorGUI.indentLevel; } }
bool DrawActionSettings(SerializedProperty property, bool expanded) { if (mFoldoutStyle == null) { mFoldoutStyle = new GUIStyle(EditorStyles.foldout) { fontStyle = FontStyle.Bold } } ; Rect r = EditorGUILayout.GetControlRect(); expanded = EditorGUI.Foldout(r, expanded, property.displayName, true, mFoldoutStyle); if (expanded) { SerializedProperty actionProp = property.FindPropertyRelative(() => def.m_Action); EditorGUILayout.PropertyField(actionProp); SerializedProperty targetProp = property.FindPropertyRelative(() => def.m_Target); bool isCustom = (actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Custom); if (!isCustom) { EditorGUILayout.PropertyField(targetProp); } bool isBoost = actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.PriorityBoost; if (isBoost) { EditorGUILayout.PropertyField(property.FindPropertyRelative(() => def.m_BoostAmount)); } bool isPlay = actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Play; if (isPlay) { SerializedProperty[] props = new SerializedProperty[2] { property.FindPropertyRelative(() => def.m_StartTime), property.FindPropertyRelative(() => def.m_Mode) }; GUIContent[] sublabels = new GUIContent[2] { GUIContent.none, new GUIContent("s", props[1].tooltip) }; InspectorUtility.MultiPropertyOnLine( EditorGUILayout.GetControlRect(), null, props, sublabels); } if (actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Custom) { EditorGUILayout.HelpBox("Use the Event() list below to call custom methods", MessageType.Info); } if (isBoost) { if (GetTargetComponent <CinemachineVirtualCameraBase>(targetProp.objectReferenceValue) == null) { EditorGUILayout.HelpBox("Target must be a CinemachineVirtualCameraBase in order to boost priority", MessageType.Warning); } } bool isEnableDisable = (actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Enable || actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Disable); if (isEnableDisable) { var value = targetProp.objectReferenceValue; if (value != null && (value as Behaviour) == null) { EditorGUILayout.HelpBox("Target must be a Behaviour in order to Enable/Disable", MessageType.Warning); } } bool isPlayStop = isPlay || actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Stop; if (isPlayStop) { if (GetTargetComponent <Animator>(targetProp.objectReferenceValue) == null && GetTargetComponent <PlayableDirector>(targetProp.objectReferenceValue) == null) { EditorGUILayout.HelpBox("Target must have a PlayableDirector or Animator in order to Play/Stop", MessageType.Warning); } } if (!isCustom && targetProp.objectReferenceValue == null) { EditorGUILayout.HelpBox("No action will be taken because target is not valid", MessageType.Info); } EditorGUILayout.Space(); EditorGUILayout.LabelField("This event will be invoked. Add calls to custom methods here:"); EditorGUILayout.PropertyField(property.FindPropertyRelative(() => def.m_Event)); } property.serializedObject.ApplyModifiedProperties(); return(expanded); } T GetTargetComponent <T>(UnityEngine.Object obj) where T : Behaviour { UnityEngine.Object currentTarget = obj; if (currentTarget != null) { GameObject targetGameObject = currentTarget as GameObject; Behaviour targetBehaviour = currentTarget as Behaviour; if (targetBehaviour != null) { targetGameObject = targetBehaviour.gameObject; } if (targetBehaviour is T) { return(targetBehaviour as T); } if (targetGameObject != null) { return(targetGameObject.GetComponent <T>()); } } return(null); } }
private void DrawComponentInspector() { const float indentSize = 15; // GML wtf get rid of this int index = (int)m_Stage; Rect rect = EditorGUILayout.GetControlRect(true); // Don't use PrefixLabel() because it will link the enabled status of field and label GUIContent label = new GUIContent(InspectorUtility.NicifyClassName(m_Stage.ToString())); if (m_StageError) { label.image = EditorGUIUtility.IconContent("console.warnicon.sml").image; } float labelWidth = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * indentSize; Rect r = rect; r.width = labelWidth; EditorGUI.LabelField(r, label); r = rect; r.width -= labelWidth; r.x += labelWidth; EditorGUI.BeginChangeCheck(); bool wasEnabled = GUI.enabled; if (TypeIsLocked) { GUI.enabled = false; } EditorGUI.showMixedValue = m_IsMixedType; m_StageSelection = EditorGUI.Popup(r, m_StageSelection, sStageData[index].PopupOptions); EditorGUI.showMixedValue = false; GUI.enabled = wasEnabled; Type type = sStageData[index].types[m_StageSelection]; if (EditorGUI.EndChangeCheck()) { SetComponent(m_Stage, type); if (m_StageSelection != 0) { sStageData[index].IsExpanded = true; } GUIUtility.ExitGUI(); return; // let the component editor be recreated } // Draw the embedded editor if (type != null) { r = new Rect(rect.x, rect.y, labelWidth, rect.height); var isExpanded = m_IsMixedType ? false : EditorGUI.Foldout( r, sStageData[index].IsExpanded, GUIContent.none, true); if (isExpanded || isExpanded != sStageData[index].IsExpanded) { // Make the editor for that stage ActiveEditorRegistry.SetActiveEditor(m_ComponentEditor, isExpanded); if (isExpanded && m_ComponentEditor != null) { ++EditorGUI.indentLevel; m_ComponentEditor.OnInspectorGUI(); --EditorGUI.indentLevel; } } sStageData[index].IsExpanded = isExpanded; } }
private void OnEnable() { m_BlendsEditor = new EmbeddeAssetEditor <CinemachineBlenderSettings>(FieldPath(x => x.m_CustomBlends), this); m_BlendsEditor.OnChanged = (CinemachineBlenderSettings b) => { InspectorUtility.RepaintGameView(); }; }
protected virtual void OnDisable() { CinemachineDebug.OnGUIHandlers -= OnGUI; InspectorUtility.RepaintGameView(Target); }