From 082499aab697dfb86ea9602a1d445e6fc7a6123d Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 10 Nov 2022 15:10:15 -0500 Subject: [PATCH] Add Foldout Groups --- .../DocAssets/FoldoutGroupsScreenshot.jpg | Bin 0 -> 59695 bytes .../ShaderGraphEditor/OpenGraphGUIEditor.cs | 127 ++++++++++++++++-- README.md | 6 +- .../OpenGraphPropertyExtension.cs | 2 +- package.json | 2 +- 5 files changed, 125 insertions(+), 12 deletions(-) create mode 100644 Documentation~/DocAssets/FoldoutGroupsScreenshot.jpg diff --git a/Documentation~/DocAssets/FoldoutGroupsScreenshot.jpg b/Documentation~/DocAssets/FoldoutGroupsScreenshot.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b48d75eab1a31c27daa3a322c697f8f4730a8530 GIT binary patch literal 59695 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

#8_6aj)3e^u13pK3a`F4 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 z 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 const float singleLineTexTabSpace = 2f; + ///

+ /// Amount of spacing above label properties. + /// + const float labelTopSpace = 4f; const string centeredSpacingName = "[centered]"; const string rightBoundSpacingName = "[rightbound]"; @@ -62,6 +66,7 @@ public class OpenGraphGUIEditor : ShaderGUI const string minFieldSpacingName = "[minfield]"; const string labelPrefix = "*"; + const string foldoutPrefix = "#"; const string singleLineTexPrefix = "%"; const string dependentVisibleTextPrefix = "^"; const string linkedPropertyPrefix = "&"; @@ -83,11 +88,26 @@ class LinkedProperty private bool fieldCenteredMode = false; private bool fieldExpandedMode = false; + private bool hadOneFoldout = false; + private bool currentlyInFoldout = false; + private int currentFoldoutIndex = 0; + private bool bottomOptionsFoldout = true; + + /// + /// Bool list for each foldout encountered. Supports up to 128 foldouts. + /// + private bool[] foldoutArray = new bool[128]; + protected Dictionary> renderExtensions = null; public OpenGraphGUIEditor() { renderExtensions = null; + for(int i = 0; i < foldoutArray.Length; i++) + { + //Initialize foldouts to show by default + foldoutArray[i] = true; + } } //BASE GUI STRUCTURE @@ -104,6 +124,8 @@ public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] pro fieldCenteredMode = false; fieldExpandedMode = false; + hadOneFoldout = false; + currentlyInFoldout = false; SetUtilityLabelWidth(); RenderPropertiesList(properties); @@ -120,6 +142,9 @@ public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] pro /// void RenderPropertiesList(MaterialProperty[] properties) { + //Track count of foldouts encountered + int foldoutCount = 0; + //Track if the last property was non-texture type or //contained a non-null input texture bool lastWasPopulated = true; @@ -147,8 +172,17 @@ void RenderPropertiesList(MaterialProperty[] properties) currentLinkedProperties.Add(thisProp.displayName, link); } + else if (thisProp.displayName.StartsWith(foldoutPrefix)) + { + //This is a foldout property + + foldoutCount++; + } } + //Reset current foldout to 0 + currentFoldoutIndex = 0; + //Now iterate across the properties for real and render them for (int i = 0; i < properties.Length; i++) { @@ -192,7 +226,7 @@ void RenderPropertiesList(MaterialProperty[] properties) //Use min field width and don't render this property SetFieldExpandedMode(false); } - else if(currentLinkedProperties.ContainsKey(propName)) + else if(currentLinkedProperties.ContainsKey(propName) && DoRenderProp()) { //This is a linked property, so check if it was rendered already var thisLinkedProp = currentLinkedProperties[propName]; @@ -210,7 +244,51 @@ void RenderPropertiesList(MaterialProperty[] properties) RenderVisibleProperty(thisLinkedProp.matProperty, propName, i); } } - else if(propName.StartsWith(labelPrefix)) + else if (propName.StartsWith(foldoutPrefix)) + { + //This is a foldout type, so create a new group + + //Trim the foldout prefix + propName = propName.Substring(foldoutPrefix.Length); + if(propName.Trim().Length > 0) + { + //There is a foldout name to use + + if(currentlyInFoldout) + { + //Stop the previous foldout + EditorGUILayout.EndFoldoutHeaderGroup(); + } + + //Update the current foldout index to the new value before setting it + currentFoldoutIndex++; + //This is done first so that later on, DoRenderProp() can tell if the last foldout is unfolded, + //While still allowing this value to change when it encountered a new foldout. + + //This actually means the first item (0) will be skipped + //But that's okay because it is never referenced. + + //Render the foldout + foldoutArray[currentFoldoutIndex] = EditorGUILayout.BeginFoldoutHeaderGroup(foldoutArray[currentFoldoutIndex], propName); + + //Finally, track that we encountered at least one foldout + hadOneFoldout = true; + //And tell the next properties that we are in a foldout + currentlyInFoldout = true; + + } + else + { + //End the last foldout if there is one + if(currentlyInFoldout) + { + EditorGUILayout.EndFoldoutHeaderGroup(); + currentlyInFoldout = false; + } + } + + } + else if(propName.StartsWith(labelPrefix) && DoRenderProp()) { //This is a label type, so show a bold header instead of the property @@ -219,7 +297,7 @@ void RenderPropertiesList(MaterialProperty[] properties) RenderLabelProperty(propName); } - else if (propName.StartsWith(dependentVisibleTextPrefix)) + else if (propName.StartsWith(dependentVisibleTextPrefix) && DoRenderProp()) { //It is dependent, so we will conditionally render it @@ -235,7 +313,7 @@ void RenderPropertiesList(MaterialProperty[] properties) //Don't render this property } } - else + else if (DoRenderProp()) { //It's not dependent, so update populated state based on this if (thisProp.type == MaterialProperty.PropType.Texture) @@ -260,11 +338,27 @@ void RenderPropertiesList(MaterialProperty[] properties) /// void RenderBottomOptions() { - matEditor.RenderQueueField(); + //If we had one foldout earlier, draw this as it's own foldout group + if(hadOneFoldout) + { + if(currentlyInFoldout) + { + EditorGUILayout.EndFoldoutHeaderGroup(); + } + bottomOptionsFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(bottomOptionsFoldout, "Advanced"); + } + + //If we don't use the group OR we do & it's unfolded, show the options + if(!hadOneFoldout || bottomOptionsFoldout) + { + matEditor.RenderQueueField(); - matEditor.EnableInstancingField(); - matEditor.DoubleSidedGIField(); - matEditor.EmissionEnabledProperty(); + matEditor.EnableInstancingField(); + matEditor.DoubleSidedGIField(); + matEditor.EmissionEnabledProperty(); + //Lightmap Emission may be a built-in only concept(?) + //matEditor.LightmapEmissionProperty(); + } } //PROPERTY RENDERING @@ -279,6 +373,7 @@ void RenderBottomOptions() /// void RenderDependentVisibleProperty(MaterialProperty v, string labelName, int index) { + //Shift over by a small amount to show the dependency EditorGUILayout.BeginHorizontal(); @@ -309,7 +404,7 @@ void RenderDependentVisibleProperty(MaterialProperty v, string labelName, int in void RenderVisibleProperty(MaterialProperty v, string labelName, int index) { - if(labelName.StartsWith(singleLineTexPrefix)) + if (labelName.StartsWith(singleLineTexPrefix)) { if(v.type == MaterialProperty.PropType.Texture) { @@ -360,6 +455,7 @@ void RenderVisibleProperty(MaterialProperty v, string labelName, int index) /// void RenderDefaultPropertyView(MaterialProperty v, string customName = "") { + string finalName = (customName == "") ? v.displayName : customName; switch(v.type) @@ -394,9 +490,22 @@ void RenderDefaultPropertyView(MaterialProperty v, string customName = "") /// void RenderLabelProperty(string propName) { + EditorGUILayout.Space(labelTopSpace); EditorGUILayout.LabelField(propName, EditorStyles.boldLabel); } + //QUERY + + /// + /// Check if we should render the current prop + /// based on foldout status. + /// + /// + bool DoRenderProp() + { + return (!currentlyInFoldout || foldoutArray[currentFoldoutIndex]); + } + //EDITOR GUI /// diff --git a/README.md b/README.md index 1ccc3c2..54126be 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The default Inspector view for ShaderGraph-based materials can be somewhat bland ## Why use OpenGraphGUI? -**OpenGraphGUI** lets you customize the appearance of your material properties right from ShaderGraph. Simply prefix your property names in the Shader's Blackboard with certain special characters, and any material using that Shader will display the custom GUI. +**OpenGraphGUI** lets you customize the appearance of your material properties right from ShaderGraph. Simply prefix your property names in the Shader's Blackboard with certain special characters, and any material using that Shader will display the custom GUI. This is a lightweight and easy to use script that provides more control over the design of your Shaders. @@ -37,6 +37,10 @@ Use a property called **\[Centered\]** to adjust the spacing of the Inspector fi +**New!** Use the **hashtag symbol (#)** as a prefix for one of your properties and you will create a Foldout Group with your property name as the title. Create up to 128 unique foldout groups by creating new foldout properties in sequence without having to tag the end of each group. If you do wish to close the previous Foldout Group, simply create a property that consists of only a **hashtag symbol (#)** without any name. The following properties will exist outside of the last group. + + + ### Property Rendering Features Prefix a texture property with the **percent symbol (%)** and it will show as a single line texture property instead of the big thumbnail version. Single line textures are commonly used in the built-in materials and offer a cleaner look that takes up less space in your Inspector. diff --git a/Samples~/DrawPropertyExtension/OpenGraphPropertyExtension.cs b/Samples~/DrawPropertyExtension/OpenGraphPropertyExtension.cs index 2da3570..d5cb3d5 100644 --- a/Samples~/DrawPropertyExtension/OpenGraphPropertyExtension.cs +++ b/Samples~/DrawPropertyExtension/OpenGraphPropertyExtension.cs @@ -18,7 +18,7 @@ public class RPOpenGraphGUIExtension : RPOpenGraphGUI /// There is one property which we can override to add our extension. /// This is done from within the constructor to improve performance. /// - public RPOpenGraphGUIExtension() + public RPOpenGraphGUIExtension() : base() { //First initialize the property renderExtensions = new Dictionary>(); diff --git a/package.json b/package.json index b9d14fe..f939e66 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.robproductions.opengraphgui", - "version": "1.1.0", + "version": "1.2.0", "displayName": "Open Graph GUI", "description": "An open-source generic Shader GUI for use with URP ShaderGraphs. This package aims to help developers clean up the look of their Material properties while maintaining the built-in style.", "unity": "2020.3",