| | |
| | | using UnityEngine; |
| | | using UnityEngine.PostProcessing; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Reflection; |
| | | |
| | | namespace UnityEditor.PostProcessing |
| | | { |
| | | //[CanEditMultipleObjects] |
| | | [CustomEditor(typeof(PostProcessingProfile))] |
| | | public class PostProcessingInspector : Editor |
| | | { |
| | | static GUIContent s_PreviewTitle = new GUIContent("Monitors"); |
| | | |
| | | PostProcessingProfile m_ConcreteTarget |
| | | { |
| | | get { return target as PostProcessingProfile; } |
| | | } |
| | | |
| | | int m_CurrentMonitorID |
| | | { |
| | | get { return m_ConcreteTarget.monitors.currentMonitorID; } |
| | | set { m_ConcreteTarget.monitors.currentMonitorID = value; } |
| | | } |
| | | |
| | | List<PostProcessingMonitor> m_Monitors; |
| | | GUIContent[] m_MonitorNames; |
| | | Dictionary<PostProcessingModelEditor, PostProcessingModel> m_CustomEditors = new Dictionary<PostProcessingModelEditor, PostProcessingModel>(); |
| | | |
| | | public bool IsInteractivePreviewOpened { get; private set; } |
| | | |
| | | void OnEnable() |
| | | { |
| | | if (target == null) |
| | | return; |
| | | |
| | | // Aggregate custom post-fx editors |
| | | var assembly = Assembly.GetAssembly(typeof(PostProcessingInspector)); |
| | | |
| | | var editorTypes = assembly.GetTypes() |
| | | .Where(x => x.IsDefined(typeof(PostProcessingModelEditorAttribute), false)); |
| | | |
| | | var customEditors = new Dictionary<Type, PostProcessingModelEditor>(); |
| | | foreach (var editor in editorTypes) |
| | | { |
| | | var attr = (PostProcessingModelEditorAttribute)editor.GetCustomAttributes(typeof(PostProcessingModelEditorAttribute), false)[0]; |
| | | var effectType = attr.type; |
| | | var alwaysEnabled = attr.alwaysEnabled; |
| | | |
| | | var editorInst = (PostProcessingModelEditor)Activator.CreateInstance(editor); |
| | | editorInst.alwaysEnabled = alwaysEnabled; |
| | | editorInst.profile = target as PostProcessingProfile; |
| | | editorInst.inspector = this; |
| | | customEditors.Add(effectType, editorInst); |
| | | } |
| | | |
| | | // ... and corresponding models |
| | | var baseType = target.GetType(); |
| | | var property = serializedObject.GetIterator(); |
| | | |
| | | while (property.Next(true)) |
| | | { |
| | | if (!property.hasChildren) |
| | | continue; |
| | | |
| | | var type = baseType; |
| | | var srcObject = ReflectionUtils.GetFieldValueFromPath(serializedObject.targetObject, ref type, property.propertyPath); |
| | | |
| | | if (srcObject == null) |
| | | continue; |
| | | |
| | | PostProcessingModelEditor editor; |
| | | if (customEditors.TryGetValue(type, out editor)) |
| | | { |
| | | var effect = (PostProcessingModel)srcObject; |
| | | |
| | | if (editor.alwaysEnabled) |
| | | effect.enabled = editor.alwaysEnabled; |
| | | |
| | | m_CustomEditors.Add(editor, effect); |
| | | editor.target = effect; |
| | | editor.serializedProperty = property.Copy(); |
| | | editor.OnPreEnable(); |
| | | } |
| | | } |
| | | |
| | | // Prepare monitors |
| | | m_Monitors = new List<PostProcessingMonitor>(); |
| | | |
| | | var monitors = new List<PostProcessingMonitor> |
| | | { |
| | | new HistogramMonitor(), |
| | | new WaveformMonitor(), |
| | | new ParadeMonitor(), |
| | | new VectorscopeMonitor() |
| | | }; |
| | | |
| | | var monitorNames = new List<GUIContent>(); |
| | | |
| | | foreach (var monitor in monitors) |
| | | { |
| | | if (monitor.IsSupported()) |
| | | { |
| | | monitor.Init(m_ConcreteTarget.monitors, this); |
| | | m_Monitors.Add(monitor); |
| | | monitorNames.Add(monitor.GetMonitorTitle()); |
| | | } |
| | | } |
| | | |
| | | m_MonitorNames = monitorNames.ToArray(); |
| | | |
| | | if (m_Monitors.Count > 0) |
| | | m_ConcreteTarget.monitors.onFrameEndEditorOnly = OnFrameEnd; |
| | | } |
| | | |
| | | void OnDisable() |
| | | { |
| | | if (m_CustomEditors != null) |
| | | { |
| | | foreach (var editor in m_CustomEditors.Keys) |
| | | editor.OnDisable(); |
| | | |
| | | m_CustomEditors.Clear(); |
| | | } |
| | | |
| | | if (m_Monitors != null) |
| | | { |
| | | foreach (var monitor in m_Monitors) |
| | | monitor.Dispose(); |
| | | |
| | | m_Monitors.Clear(); |
| | | } |
| | | |
| | | if (m_ConcreteTarget != null) |
| | | m_ConcreteTarget.monitors.onFrameEndEditorOnly = null; |
| | | } |
| | | |
| | | void OnFrameEnd(RenderTexture source) |
| | | { |
| | | if (!IsInteractivePreviewOpened) |
| | | return; |
| | | |
| | | if (m_CurrentMonitorID < m_Monitors.Count) |
| | | m_Monitors[m_CurrentMonitorID].OnFrameData(source); |
| | | |
| | | IsInteractivePreviewOpened = false; |
| | | } |
| | | |
| | | public override void OnInspectorGUI() |
| | | { |
| | | serializedObject.Update(); |
| | | |
| | | // Handles undo/redo events first (before they get used by the editors' widgets) |
| | | var e = Event.current; |
| | | if (e.type == EventType.ValidateCommand && e.commandName == "UndoRedoPerformed") |
| | | { |
| | | foreach (var editor in m_CustomEditors) |
| | | editor.Value.OnValidate(); |
| | | } |
| | | |
| | | if (!m_ConcreteTarget.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.None)) |
| | | EditorGUILayout.HelpBox("A debug view is currently enabled. Changes done to an effect might not be visible.", MessageType.Info); |
| | | |
| | | foreach (var editor in m_CustomEditors) |
| | | { |
| | | EditorGUI.BeginChangeCheck(); |
| | | |
| | | editor.Key.OnGUI(); |
| | | |
| | | if (EditorGUI.EndChangeCheck()) |
| | | editor.Value.OnValidate(); |
| | | } |
| | | |
| | | serializedObject.ApplyModifiedProperties(); |
| | | } |
| | | |
| | | public override GUIContent GetPreviewTitle() |
| | | { |
| | | return s_PreviewTitle; |
| | | } |
| | | |
| | | public override bool HasPreviewGUI() |
| | | { |
| | | return GraphicsUtils.supportsDX11 && m_Monitors.Count > 0; |
| | | } |
| | | |
| | | public override void OnPreviewSettings() |
| | | { |
| | | using (new EditorGUILayout.HorizontalScope()) |
| | | { |
| | | if (m_CurrentMonitorID < m_Monitors.Count) |
| | | m_Monitors[m_CurrentMonitorID].OnMonitorSettings(); |
| | | |
| | | GUILayout.Space(5); |
| | | m_CurrentMonitorID = EditorGUILayout.Popup(m_CurrentMonitorID, m_MonitorNames, FxStyles.preDropdown, GUILayout.MaxWidth(100f)); |
| | | } |
| | | } |
| | | |
| | | public override void OnInteractivePreviewGUI(Rect r, GUIStyle background) |
| | | { |
| | | IsInteractivePreviewOpened = true; |
| | | |
| | | if (m_CurrentMonitorID < m_Monitors.Count) |
| | | m_Monitors[m_CurrentMonitorID].OnMonitorGUI(r); |
| | | } |
| | | } |
| | | } |
| | | using UnityEngine;
|
| | | using UnityEngine.PostProcessing;
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Linq;
|
| | | using System.Reflection;
|
| | |
|
| | | namespace UnityEditor.PostProcessing
|
| | | {
|
| | | //[CanEditMultipleObjects]
|
| | | [CustomEditor(typeof(PostProcessingProfile))]
|
| | | public class PostProcessingInspector : Editor
|
| | | {
|
| | | static GUIContent s_PreviewTitle = new GUIContent("Monitors");
|
| | |
|
| | | PostProcessingProfile m_ConcreteTarget
|
| | | {
|
| | | get { return target as PostProcessingProfile; }
|
| | | }
|
| | |
|
| | | int m_CurrentMonitorID
|
| | | {
|
| | | get { return m_ConcreteTarget.monitors.currentMonitorID; }
|
| | | set { m_ConcreteTarget.monitors.currentMonitorID = value; }
|
| | | }
|
| | |
|
| | | List<PostProcessingMonitor> m_Monitors;
|
| | | GUIContent[] m_MonitorNames;
|
| | | Dictionary<PostProcessingModelEditor, PostProcessingModel> m_CustomEditors = new Dictionary<PostProcessingModelEditor, PostProcessingModel>();
|
| | |
|
| | | public bool IsInteractivePreviewOpened { get; private set; }
|
| | |
|
| | | void OnEnable()
|
| | | {
|
| | | if (target == null)
|
| | | return;
|
| | |
|
| | | // Aggregate custom post-fx editors
|
| | | var assembly = Assembly.GetAssembly(typeof(PostProcessingInspector));
|
| | |
|
| | | var editorTypes = assembly.GetTypes()
|
| | | .Where(x => x.IsDefined(typeof(PostProcessingModelEditorAttribute), false));
|
| | |
|
| | | var customEditors = new Dictionary<Type, PostProcessingModelEditor>();
|
| | | foreach (var editor in editorTypes)
|
| | | {
|
| | | var attr = (PostProcessingModelEditorAttribute)editor.GetCustomAttributes(typeof(PostProcessingModelEditorAttribute), false)[0];
|
| | | var effectType = attr.type;
|
| | | var alwaysEnabled = attr.alwaysEnabled;
|
| | |
|
| | | var editorInst = (PostProcessingModelEditor)Activator.CreateInstance(editor);
|
| | | editorInst.alwaysEnabled = alwaysEnabled;
|
| | | editorInst.profile = target as PostProcessingProfile;
|
| | | editorInst.inspector = this;
|
| | | customEditors.Add(effectType, editorInst);
|
| | | }
|
| | |
|
| | | // ... and corresponding models
|
| | | var baseType = target.GetType();
|
| | | var property = serializedObject.GetIterator();
|
| | |
|
| | | while (property.Next(true))
|
| | | {
|
| | | if (!property.hasChildren)
|
| | | continue;
|
| | |
|
| | | var type = baseType;
|
| | | var srcObject = ReflectionUtils.GetFieldValueFromPath(serializedObject.targetObject, ref type, property.propertyPath);
|
| | |
|
| | | if (srcObject == null)
|
| | | continue;
|
| | |
|
| | | PostProcessingModelEditor editor;
|
| | | if (customEditors.TryGetValue(type, out editor))
|
| | | {
|
| | | var effect = (PostProcessingModel)srcObject;
|
| | |
|
| | | if (editor.alwaysEnabled)
|
| | | effect.enabled = editor.alwaysEnabled;
|
| | |
|
| | | m_CustomEditors.Add(editor, effect);
|
| | | editor.target = effect;
|
| | | editor.serializedProperty = property.Copy();
|
| | | editor.OnPreEnable();
|
| | | }
|
| | | }
|
| | |
|
| | | // Prepare monitors
|
| | | m_Monitors = new List<PostProcessingMonitor>();
|
| | |
|
| | | var monitors = new List<PostProcessingMonitor>
|
| | | {
|
| | | new HistogramMonitor(),
|
| | | new WaveformMonitor(),
|
| | | new ParadeMonitor(),
|
| | | new VectorscopeMonitor()
|
| | | };
|
| | |
|
| | | var monitorNames = new List<GUIContent>();
|
| | |
|
| | | foreach (var monitor in monitors)
|
| | | {
|
| | | if (monitor.IsSupported())
|
| | | {
|
| | | monitor.Init(m_ConcreteTarget.monitors, this);
|
| | | m_Monitors.Add(monitor);
|
| | | monitorNames.Add(monitor.GetMonitorTitle());
|
| | | }
|
| | | }
|
| | |
|
| | | m_MonitorNames = monitorNames.ToArray();
|
| | |
|
| | | if (m_Monitors.Count > 0)
|
| | | m_ConcreteTarget.monitors.onFrameEndEditorOnly = OnFrameEnd;
|
| | | }
|
| | |
|
| | | void OnDisable()
|
| | | {
|
| | | if (m_CustomEditors != null)
|
| | | {
|
| | | foreach (var editor in m_CustomEditors.Keys)
|
| | | editor.OnDisable();
|
| | |
|
| | | m_CustomEditors.Clear();
|
| | | }
|
| | |
|
| | | if (m_Monitors != null)
|
| | | {
|
| | | foreach (var monitor in m_Monitors)
|
| | | monitor.Dispose();
|
| | |
|
| | | m_Monitors.Clear();
|
| | | }
|
| | |
|
| | | if (m_ConcreteTarget != null)
|
| | | m_ConcreteTarget.monitors.onFrameEndEditorOnly = null;
|
| | | }
|
| | |
|
| | | void OnFrameEnd(RenderTexture source)
|
| | | {
|
| | | if (!IsInteractivePreviewOpened)
|
| | | return;
|
| | |
|
| | | if (m_CurrentMonitorID < m_Monitors.Count)
|
| | | m_Monitors[m_CurrentMonitorID].OnFrameData(source);
|
| | |
|
| | | IsInteractivePreviewOpened = false;
|
| | | }
|
| | |
|
| | | public override void OnInspectorGUI()
|
| | | {
|
| | | serializedObject.Update();
|
| | |
|
| | | // Handles undo/redo events first (before they get used by the editors' widgets)
|
| | | var e = Event.current;
|
| | | if (e.type == EventType.ValidateCommand && e.commandName == "UndoRedoPerformed")
|
| | | {
|
| | | foreach (var editor in m_CustomEditors)
|
| | | editor.Value.OnValidate();
|
| | | }
|
| | |
|
| | | if (!m_ConcreteTarget.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.None))
|
| | | EditorGUILayout.HelpBox("A debug view is currently enabled. Changes done to an effect might not be visible.", MessageType.Info);
|
| | |
|
| | | foreach (var editor in m_CustomEditors)
|
| | | {
|
| | | EditorGUI.BeginChangeCheck();
|
| | |
|
| | | editor.Key.OnGUI();
|
| | |
|
| | | if (EditorGUI.EndChangeCheck())
|
| | | editor.Value.OnValidate();
|
| | | }
|
| | |
|
| | | serializedObject.ApplyModifiedProperties();
|
| | | }
|
| | |
|
| | | public override GUIContent GetPreviewTitle()
|
| | | {
|
| | | return s_PreviewTitle;
|
| | | }
|
| | |
|
| | | public override bool HasPreviewGUI()
|
| | | {
|
| | | return GraphicsUtils.supportsDX11 && m_Monitors.Count > 0;
|
| | | }
|
| | |
|
| | | public override void OnPreviewSettings()
|
| | | {
|
| | | using (new EditorGUILayout.HorizontalScope())
|
| | | {
|
| | | if (m_CurrentMonitorID < m_Monitors.Count)
|
| | | m_Monitors[m_CurrentMonitorID].OnMonitorSettings();
|
| | |
|
| | | GUILayout.Space(5);
|
| | | m_CurrentMonitorID = EditorGUILayout.Popup(m_CurrentMonitorID, m_MonitorNames, FxStyles.preDropdown, GUILayout.MaxWidth(100f));
|
| | | }
|
| | | }
|
| | |
|
| | | public override void OnInteractivePreviewGUI(Rect r, GUIStyle background)
|
| | | {
|
| | | IsInteractivePreviewOpened = true;
|
| | |
|
| | | if (m_CurrentMonitorID < m_Monitors.Count)
|
| | | m_Monitors[m_CurrentMonitorID].OnMonitorGUI(r);
|
| | | }
|
| | | }
|
| | | }
|