예제 #1
0
        void DoStandardModeGUI(bool hdr)
        {
            if (!hdr)
            {
                PropertyField(m_LdrLut);

                var lut = (target as ColorGrading).ldrLut.value;
                CheckLutImportSettings(lut);
            }

            if (hdr)
            {
                EditorGUILayout.Space();
                EditorUtilities.DrawHeaderLabel("Tonemapping");
                PropertyField(m_Tonemapper);

                if (m_Tonemapper.value.intValue == (int)Tonemapper.Custom)
                {
                    DrawCustomToneCurve();
                    PropertyField(m_ToneCurveToeStrength);
                    PropertyField(m_ToneCurveToeLength);
                    PropertyField(m_ToneCurveShoulderStrength);
                    PropertyField(m_ToneCurveShoulderLength);
                    PropertyField(m_ToneCurveShoulderAngle);
                    PropertyField(m_ToneCurveGamma);
                }
            }

            EditorGUILayout.Space();
            EditorUtilities.DrawHeaderLabel("White Balance");

            PropertyField(m_Temperature);
            PropertyField(m_Tint);

            EditorGUILayout.Space();
            EditorUtilities.DrawHeaderLabel("Tone");

            if (hdr)
            {
                PropertyField(m_PostExposure);
            }

            PropertyField(m_ColorFilter);
            PropertyField(m_HueShift);
            PropertyField(m_Saturation);

            if (!hdr)
            {
                PropertyField(m_Brightness);
            }

            PropertyField(m_Contrast);

            EditorGUILayout.Space();
            int currentChannel = GlobalSettings.currentChannelMixer;

            using (new EditorGUILayout.HorizontalScope())
            {
                EditorGUILayout.PrefixLabel("Channel Mixer", GUIStyle.none, Styling.labelHeader);

                EditorGUI.BeginChangeCheck();
                {
                    using (new EditorGUILayout.HorizontalScope())
                    {
                        GUILayoutUtility.GetRect(9f, 18f, GUILayout.ExpandWidth(false)); // Dirty hack to do proper right column alignement
                        if (GUILayout.Toggle(currentChannel == 0, EditorUtilities.GetContent("Red|Red output channel."), EditorStyles.miniButtonLeft))
                        {
                            currentChannel = 0;
                        }
                        if (GUILayout.Toggle(currentChannel == 1, EditorUtilities.GetContent("Green|Green output channel."), EditorStyles.miniButtonMid))
                        {
                            currentChannel = 1;
                        }
                        if (GUILayout.Toggle(currentChannel == 2, EditorUtilities.GetContent("Blue|Blue output channel."), EditorStyles.miniButtonRight))
                        {
                            currentChannel = 2;
                        }
                    }
                }
                if (EditorGUI.EndChangeCheck())
                {
                    GUI.FocusControl(null);
                }
            }

            GlobalSettings.currentChannelMixer = currentChannel;

            if (currentChannel == 0)
            {
                PropertyField(m_MixerRedOutRedIn);
                PropertyField(m_MixerRedOutGreenIn);
                PropertyField(m_MixerRedOutBlueIn);
            }
            else if (currentChannel == 1)
            {
                PropertyField(m_MixerGreenOutRedIn);
                PropertyField(m_MixerGreenOutGreenIn);
                PropertyField(m_MixerGreenOutBlueIn);
            }
            else
            {
                PropertyField(m_MixerBlueOutRedIn);
                PropertyField(m_MixerBlueOutGreenIn);
                PropertyField(m_MixerBlueOutBlueIn);
            }

            EditorGUILayout.Space();
            EditorUtilities.DrawHeaderLabel("Trackballs");

            using (new EditorGUILayout.HorizontalScope())
            {
                PropertyField(m_Lift);
                GUILayout.Space(4f);
                PropertyField(m_Gamma);
                GUILayout.Space(4f);
                PropertyField(m_Gain);
            }

            EditorGUILayout.Space();
            EditorUtilities.DrawHeaderLabel("Grading Curves");

            DoCurvesGUI(hdr);
        }
예제 #2
0
 void CurveOverrideToggle(SerializedProperty overrideProp)
 {
     overrideProp.boolValue = GUILayout.Toggle(overrideProp.boolValue, EditorUtilities.GetContent("Override"), EditorStyles.toolbarButton);
 }
예제 #3
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            EditorGUILayout.PropertyField(m_IsGlobal);

            if (!m_IsGlobal.boolValue) // Blend radius is not needed for global volumes
            {
                EditorGUILayout.PropertyField(m_BlendRadius);
            }

            EditorGUILayout.PropertyField(m_Weight);
            EditorGUILayout.PropertyField(m_Priority);

            bool assetHasChanged = false;
            bool showCopy        = m_Profile.objectReferenceValue != null;

            // The layout system sort of break alignement when mixing inspector fields with custom
            // layouted fields, do the layout manually instead
            int   buttonWidth    = showCopy ? 45 : 60;
            float indentOffset   = EditorGUI.indentLevel * 15f;
            var   lineRect       = GUILayoutUtility.GetRect(1, EditorGUIUtility.singleLineHeight);
            var   labelRect      = new Rect(lineRect.x, lineRect.y, EditorGUIUtility.labelWidth - indentOffset, lineRect.height);
            var   fieldRect      = new Rect(labelRect.xMax, lineRect.y, lineRect.width - labelRect.width - buttonWidth * (showCopy ? 2 : 1), lineRect.height);
            var   buttonNewRect  = new Rect(fieldRect.xMax, lineRect.y, buttonWidth, lineRect.height);
            var   buttonCopyRect = new Rect(buttonNewRect.xMax, lineRect.y, buttonWidth, lineRect.height);

            EditorGUI.PrefixLabel(labelRect, EditorUtilities.GetContent("Profile|A reference to a profile asset."));

            using (var scope = new EditorGUI.ChangeCheckScope())
            {
                m_Profile.objectReferenceValue = (PostProcessProfile)EditorGUI.ObjectField(fieldRect, m_Profile.objectReferenceValue, typeof(PostProcessProfile), false);
                assetHasChanged = scope.changed;
            }

            if (GUI.Button(buttonNewRect, EditorUtilities.GetContent("New|Create a new profile."), showCopy ? EditorStyles.miniButtonLeft : EditorStyles.miniButton))
            {
                // By default, try to put assets in a folder next to the currently active
                // scene file. If the user isn't a scene, put them in root instead.
                var targetName = m_Target.name;
                var scene      = m_Target.gameObject.scene;
                var asset      = ProfileFactory.CreatePostProcessProfile(scene, targetName);
                m_Profile.objectReferenceValue = asset;
                assetHasChanged = true;
            }

            if (showCopy && GUI.Button(buttonCopyRect, EditorUtilities.GetContent("Clone|Create a new profile and copy the content of the currently assigned profile."), EditorStyles.miniButtonRight))
            {
                // Duplicate the currently assigned profile and save it as a new profile
                var origin = (PostProcessProfile)m_Profile.objectReferenceValue;
                var path   = AssetDatabase.GetAssetPath(origin);
                path = AssetDatabase.GenerateUniqueAssetPath(path);

                var asset = Instantiate(origin);
                asset.settings.Clear();
                AssetDatabase.CreateAsset(asset, path);

                foreach (var item in origin.settings)
                {
                    var itemCopy = Instantiate(item);
                    itemCopy.hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy;
                    itemCopy.name      = item.name;
                    asset.settings.Add(itemCopy);
                    AssetDatabase.AddObjectToAsset(itemCopy, asset);
                }

                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();

                m_Profile.objectReferenceValue = asset;
                assetHasChanged = true;
            }

            EditorGUILayout.Space();

            if (m_Profile.objectReferenceValue == null)
            {
                if (assetHasChanged)
                {
                    m_EffectList.Clear(); // Asset wasn't null before, do some cleanup
                }
                EditorGUILayout.HelpBox("Assign a Post-process Profile to this volume using the \"Asset\" field or create one automatically by clicking the \"New\" button.\nAssets are automatically put in a folder next to your scene file. If you scene hasn't been saved yet they will be created at the root of the Assets folder.", MessageType.Info);
            }
            else
            {
                if (assetHasChanged)
                {
                    RefreshEffectListEditor((PostProcessProfile)m_Profile.objectReferenceValue);
                }

                m_EffectList.OnGUI();
            }

            serializedObject.ApplyModifiedProperties();
        }
예제 #4
0
        public void OnGUI()
        {
            if (m_Asset == null)
            {
                return;
            }

            if (m_Asset.isDirty)
            {
                RefreshEditors();
                m_Asset.isDirty = false;
            }

            var isEditable = !Provider.isActive ||
                             AssetDatabase.IsOpenForEdit(m_Asset, StatusQueryOptions.UseCachedIfPossible);

            using (new EditorGUI.DisabledScope(!isEditable))
            {
                EditorGUILayout.LabelField(EditorUtilities.GetContent("Overrides"), EditorStyles.boldLabel);

                // Override list
                for (var i = 0; i < m_Editors.Count; i++)
                {
                    var editor = m_Editors[i];
                    var title  = editor.GetDisplayTitle();
                    var id     = i; // Needed for closure capture below

                    EditorUtilities.DrawSplitter();
                    var displayContent = EditorUtilities.DrawHeader(
                        title,
                        editor.baseProperty,
                        editor.activeProperty,
                        editor.target,
                        () => ResetEffectOverride(editor.target.GetType(), id),
                        () => RemoveEffectOverride(id)
                        );

                    if (displayContent)
                    {
                        using (new EditorGUI.DisabledScope(!editor.activeProperty.boolValue))
                        {
                            editor.OnInternalInspectorGUI();
                        }
                    }
                }

                if (m_Editors.Count > 0)
                {
                    EditorUtilities.DrawSplitter();
                    EditorGUILayout.Space();
                }
                else
                {
                    EditorGUILayout.HelpBox("No override set on this volume.", MessageType.Info);
                }

                if (GUILayout.Button("Add effect...", EditorStyles.miniButton))
                {
                    var menu = new GenericMenu();

                    var typeMap = PostProcessManager.instance.settingsTypes;
                    foreach (var kvp in typeMap)
                    {
                        var type   = kvp.Key;
                        var title  = EditorUtilities.GetContent(kvp.Value.menuItem);
                        var exists = m_Asset.HasSettings(type);

                        if (!exists)
                        {
                            menu.AddItem(title, false, () => AddEffectOverride(type));
                        }
                        else
                        {
                            menu.AddDisabledItem(title);
                        }
                    }

                    menu.ShowAsContext();
                }

                EditorGUILayout.Space();
            }
        }
예제 #5
0
        void DoCustomEffectSorter()
        {
            EditorUtilities.DrawSplitter();
            m_ShowCustomSorter.boolValue = EditorUtilities.DrawHeader("Custom Effect Sorting", m_ShowCustomSorter.boolValue);

            if (m_ShowCustomSorter.boolValue)
            {
                bool isInPrefab = false;

                // Init lists if needed
                if (m_CustomLists == null)
                {
                    // In some cases the editor will refresh before components which means
                    // components might not have been fully initialized yet. In this case we also
                    // need to make sure that we're not in a prefab as sorteBundles isn't a
                    // serializable object and won't exist until put on a scene.
                    if (m_Target.sortedBundles == null)
                    {
                        isInPrefab = string.IsNullOrEmpty(m_Target.gameObject.scene.name);

                        if (!isInPrefab)
                        {
                            // sortedBundles will be initialized and ready to use on the next frame
                            Repaint();
                        }
                    }
                    else
                    {
                        // Create a reorderable list for each injection event
                        m_CustomLists = new Dictionary <PostProcessEvent, ReorderableList>();
                        foreach (var evt in Enum.GetValues(typeof(PostProcessEvent)).Cast <PostProcessEvent>())
                        {
                            var bundles  = m_Target.sortedBundles[evt];
                            var listName = ObjectNames.NicifyVariableName(evt.ToString());

                            var list = new ReorderableList(bundles, typeof(SerializedBundleRef), true, true, false, false);

                            list.drawHeaderCallback = (rect) =>
                            {
                                EditorGUI.LabelField(rect, listName);
                            };

                            list.drawElementCallback = (rect, index, isActive, isFocused) =>
                            {
                                var sbr = (SerializedBundleRef)list.list[index];
                                EditorGUI.LabelField(rect, sbr.bundle.attribute.menuItem);
                            };

                            list.onReorderCallback = (l) =>
                            {
                                EditorUtility.SetDirty(m_Target);
                            };

                            m_CustomLists.Add(evt, list);
                        }
                    }
                }

                GUILayout.Space(5);

                if (isInPrefab)
                {
                    EditorGUILayout.HelpBox("Not supported in prefabs.", MessageType.Info);
                    GUILayout.Space(3);
                    return;
                }

                bool anyList = false;
                if (m_CustomLists != null)
                {
                    foreach (var kvp in m_CustomLists)
                    {
                        var list = kvp.Value;

                        // Skip empty lists to avoid polluting the inspector
                        if (list.count == 0)
                        {
                            continue;
                        }

                        list.DoLayoutList();
                        anyList = true;
                    }
                }

                if (!anyList)
                {
                    EditorGUILayout.HelpBox("No custom effect loaded.", MessageType.Info);
                    GUILayout.Space(3);
                }
            }
        }
        protected void PropertyField(SerializedParameterOverride property)
        {
            var title = EditorUtilities.GetContent(property.displayName);

            PropertyField(property, title);
        }
        protected void PropertyField(SerializedParameterOverride property, GUIContent title)
        {
            // Check for DisplayNameAttribute first
            var displayNameAttr = property.GetAttribute <DisplayNameAttribute>();

            if (displayNameAttr != null)
            {
                title.text = displayNameAttr.displayName;
            }

            // Add tooltip if it's missing and an attribute is available
            if (string.IsNullOrEmpty(title.tooltip))
            {
                var tooltipAttr = property.GetAttribute <TooltipAttribute>();
                if (tooltipAttr != null)
                {
                    title.tooltip = tooltipAttr.tooltip;
                }
            }

            // Look for a compatible attribute decorator
            AttributeDecorator decorator = null;
            Attribute          attribute = null;

            foreach (var attr in property.attributes)
            {
                // Use the first decorator we found
                if (decorator == null)
                {
                    decorator = EditorUtilities.GetDecorator(attr.GetType());
                    attribute = attr;
                }

                // Draw unity built-in Decorators (Space, Header)
                if (attr is PropertyAttribute)
                {
                    if (attr is SpaceAttribute)
                    {
                        EditorGUILayout.GetControlRect(false, (attr as SpaceAttribute).height);
                    }
                    else if (attr is HeaderAttribute)
                    {
                        var rect = EditorGUILayout.GetControlRect(false, 24f);
                        rect.y += 8f;
                        rect    = EditorGUI.IndentedRect(rect);
                        EditorGUI.LabelField(rect, (attr as HeaderAttribute).header, Styling.labelHeader);
                    }
                }
            }

            bool invalidProp = false;

            if (decorator != null && !decorator.IsAutoProperty())
            {
                if (decorator.OnGUI(property.value, property.overrideState, title, attribute))
                {
                    return;
                }

                // Attribute is invalid for the specified property; use default unity field instead
                invalidProp = true;
            }

            using (new EditorGUILayout.HorizontalScope())
            {
                // Override checkbox
                var overrideRect = GUILayoutUtility.GetRect(17f, 17f, GUILayout.ExpandWidth(false));
                overrideRect.yMin += 4f;
                EditorUtilities.DrawOverrideCheckbox(overrideRect, property.overrideState);

                // Property
                using (new EditorGUI.DisabledScope(!property.overrideState.boolValue))
                {
                    if (decorator != null && !invalidProp)
                    {
                        if (decorator.OnGUI(property.value, property.overrideState, title, attribute))
                        {
                            return;
                        }
                    }

                    // Default unity field
                    if (property.value.hasVisibleChildren &&
                        property.value.propertyType != SerializedPropertyType.Vector2 &&
                        property.value.propertyType != SerializedPropertyType.Vector3)
                    {
                        GUILayout.Space(12f);
                        EditorGUILayout.PropertyField(property.value, title, true);
                    }
                    else
                    {
                        EditorGUILayout.PropertyField(property.value, title);
                    }
                }
            }
        }