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); }
void CurveOverrideToggle(SerializedProperty overrideProp) { overrideProp.boolValue = GUILayout.Toggle(overrideProp.boolValue, EditorUtilities.GetContent("Override"), EditorStyles.toolbarButton); }
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(); }
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(); } }
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); } } } }