| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 | using UnityEngine;using UnityEditor;using UnityEditor.Rendering;using System.Collections.Generic;using System.Linq;using System.Reflection;namespace HorizonBasedAmbientOcclusion{    [CustomEditor(typeof(HBAO))]    public class HBAOEditor : Editor    {        private HBAO m_HBAO;        private Texture2D m_HBAOTex;        private GUIStyle m_SettingsGroupStyle;        private GUIStyle m_TitleLabelStyle;        private int m_SelectedPreset;        // settings group <setting, property reference>        private Dictionary<FieldInfo, List<SerializedProperty>> m_GroupFields = new Dictionary<FieldInfo, List<SerializedProperty>>();        private readonly Dictionary<int, HBAO.Preset> m_Presets = new Dictionary<int, HBAO.Preset>()        {            { 0, HBAO.Preset.Normal },            { 1, HBAO.Preset.FastPerformance },            { 2, HBAO.Preset.FastestPerformance },            { 3, HBAO.Preset.Custom },            { 4, HBAO.Preset.HighQuality },            { 5, HBAO.Preset.HighestQuality }        };        void OnEnable()        {            m_HBAO = (HBAO)target;            m_HBAOTex = Resources.Load<Texture2D>("hbao");            var settingsGroups = typeof(HBAO).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)                    .Where(x => x.GetCustomAttributes(typeof(HBAO.SettingsGroup), false).Any());            foreach (var group in settingsGroups)            {                foreach (var setting in group.FieldType.GetFields(BindingFlags.Instance | BindingFlags.Public))                {                    if (!m_GroupFields.ContainsKey(group))                        m_GroupFields[group] = new List<SerializedProperty>();                    var property = serializedObject.FindProperty(group.Name + "." + setting.Name);                    if (property != null)                        m_GroupFields[group].Add(property);                }            }            m_SelectedPreset = m_Presets.Values.ToList().IndexOf(m_HBAO.GetCurrentPreset());        }        public override void OnInspectorGUI()        {            serializedObject.Update();            SetStyles();            EditorGUILayout.BeginVertical();            {                // header                GUILayout.Space(10.0f);                GUILayout.Label(m_HBAOTex, m_TitleLabelStyle, GUILayout.ExpandWidth(true));                //if (m_HBAO.GetComponents<MonoBehaviour>()[0] != m_HBAO)                //{                //GUILayout.Space(6.0f);                //EditorGUILayout.HelpBox("This Post FX should be one of the first in your effect stack", MessageType.Info);                //}                Event e = Event.current;                // settings groups                foreach (var group in m_GroupFields)                {                    var groupProperty = serializedObject.FindProperty(group.Key.Name);                    if (groupProperty == null)                        continue;                    GUILayout.Space(6.0f);                    Rect rect = GUILayoutUtility.GetRect(16f, 22f, m_SettingsGroupStyle);                    GUI.Box(rect, ObjectNames.NicifyVariableName(groupProperty.displayName), m_SettingsGroupStyle);                    if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition))                    {                        groupProperty.isExpanded = !groupProperty.isExpanded;                        e.Use();                    }                    if (!groupProperty.isExpanded)                        continue;                    // presets is a special case                    if (group.Key.FieldType == typeof(HBAO.Presets))                    {                        GUILayout.Space(6.0f);                        m_SelectedPreset = GUILayout.SelectionGrid(m_SelectedPreset, m_Presets.Values.Select(x => ObjectNames.NicifyVariableName(x.ToString())).ToArray(), 3);                        GUILayout.Space(6.0f);                        if (GUILayout.Button("Apply Preset"))                        {                            Undo.RecordObject(target, "Apply Preset");                            m_HBAO.ApplyPreset(m_Presets[m_SelectedPreset]);                            EditorUtility.SetDirty(target);                            if (!EditorApplication.isPlaying)                            {                                UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene());                            }                        }                    }                    foreach (var field in group.Value)                    {                        // hide real presets                        if (group.Key.FieldType == typeof(HBAO.Presets))                            continue;                        // hide resolution when deinterleaved HBAO is on                        if (group.Key.FieldType == typeof(HBAO.GeneralSettings) && field.name == "resolution")                        {                            if (m_HBAO.GetDeinterleaving() != HBAO.Deinterleaving.Disabled)                            {                                continue;                            }                        }                        // warn about deinterleaving not supported with SPSR                        else if (group.Key.FieldType == typeof(HBAO.GeneralSettings) && field.name == "debugMode")                        {#if UNITY_2019_3_OR_NEWER                        if (m_HBAO.GetDeinterleaving() != HBAO.Deinterleaving.Disabled &&                            IsVrRunning() && PlayerSettings.stereoRenderingPath == StereoRenderingPath.SinglePass)                        {                            GUILayout.Space(6.0f);                            EditorGUILayout.HelpBox("Deinterleaving is not supported with Single Pass Stereo Rendering...", MessageType.Warning);                        }#else                            if (m_HBAO.GetDeinterleaving() != HBAO.Deinterleaving.Disabled &&                                PlayerSettings.virtualRealitySupported && PlayerSettings.stereoRenderingPath == StereoRenderingPath.SinglePass)                            {                                GUILayout.Space(6.0f);                                EditorGUILayout.HelpBox("Deinterleaving is not supported with Single Pass Stereo Rendering...", MessageType.Warning);                            }#endif                        }                        // hide noise type when deinterleaved HBAO is on                        else if (group.Key.FieldType == typeof(HBAO.GeneralSettings) && field.name == "noiseType")                        {                            if (m_HBAO.GetDeinterleaving() != HBAO.Deinterleaving.Disabled)                            {                                continue;                            }                        }                        // hide useMultiBounce setting in BeforeReflections integration stage                        else if (group.Key.FieldType == typeof(HBAO.AOSettings) && field.name == "useMultiBounce")                        {                            if (m_HBAO.GetPipelineStage() == HBAO.PipelineStage.BeforeReflections)                            {                                continue;                            }                        }                        // hide multiBounceInfluence setting when not used                        else if (group.Key.FieldType == typeof(HBAO.AOSettings) && field.name == "multiBounceInfluence")                        {                            if (m_HBAO.GetPipelineStage() == HBAO.PipelineStage.BeforeReflections || !m_HBAO.UseMultiBounce())                            {                                continue;                            }                        }                        // warn about distance falloff greater than max distance                        else if (group.Key.FieldType == typeof(HBAO.AOSettings) && field.name == "perPixelNormals")                        {                            if (m_HBAO.GetAoDistanceFalloff() > m_HBAO.GetAoMaxDistance())                            {                                GUILayout.Space(6.0f);                                EditorGUILayout.HelpBox("Distance Falloff shoudn't be superior to Max Distance", MessageType.Warning);                            }                        }                        // hide albedoMultiplier when not in deferred                        else if (group.Key.FieldType == typeof(HBAO.ColorBleedingSettings) && field.name == "albedoMultiplier")                        {                            if (m_HBAO.GetPipelineStage() == HBAO.PipelineStage.BeforeImageEffectsOpaque)                                continue;                        }                        EditorGUILayout.BeginHorizontal();                        GUILayout.Space(12.0f);                        EditorGUILayout.PropertyField(field);                        EditorGUILayout.EndHorizontal();                    }                }            }            EditorGUILayout.EndVertical();            serializedObject.ApplyModifiedProperties();        }        private void SetStyles()        {            // set banner label style            m_TitleLabelStyle = new GUIStyle(GUI.skin.label);            m_TitleLabelStyle.alignment = TextAnchor.MiddleCenter;            m_TitleLabelStyle.contentOffset = new Vector2(0f, 0f);            // get shuriken module title style            GUIStyle skurikenModuleTitleStyle = "ShurikenModuleTitle";            // clone it as to not interfere with the original, and adjust it            m_SettingsGroupStyle = new GUIStyle(skurikenModuleTitleStyle);            m_SettingsGroupStyle.font = (new GUIStyle("Label")).font;            m_SettingsGroupStyle.fontStyle = FontStyle.Bold;            m_SettingsGroupStyle.border = new RectOffset(15, 7, 4, 4);            m_SettingsGroupStyle.fixedHeight = 22;            m_SettingsGroupStyle.contentOffset = new Vector2(10f, -2f);        }#if UNITY_2019_3_OR_NEWER        List<UnityEngine.XR.XRDisplaySubsystemDescriptor> displaysDescs = new List<UnityEngine.XR.XRDisplaySubsystemDescriptor>();        List<UnityEngine.XR.XRDisplaySubsystem> displays = new List<UnityEngine.XR.XRDisplaySubsystem>();        private bool IsVrRunning()        {            bool vrIsRunning = false;            displays.Clear();            SubsystemManager.GetInstances(displays);            foreach (var displaySubsystem in displays)            {                if (displaySubsystem.running)                {                    vrIsRunning = true;                    break;                }            }            return vrIsRunning;        }#endif        [CustomPropertyDrawer(typeof(HBAO.MinMaxSliderAttribute))]        public class MinMaxSliderDrawer : PropertyDrawer        {            public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)            {                if (property.propertyType == SerializedPropertyType.Vector2)                {                    Vector2 range = property.vector2Value;                    float min = range.x;                    float max = range.y;                    var attr = attribute as HBAO.MinMaxSliderAttribute;                    EditorGUI.BeginChangeCheck();                    EditorGUI.MinMaxSlider(position, label, ref min, ref max, attr.min, attr.max);                    if (EditorGUI.EndChangeCheck())                    {                        range.x = min;                        range.y = max;                        property.vector2Value = range;                    }                }                else                {                    EditorGUI.LabelField(position, label, "Use only with Vector2");                }            }        }    }}
 |