diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..a595e27
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,34 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+## [Unreleased]
+
+## [1.3.0] - 2023-12-14
+
+### Added
+
+- Added Vector prefix feature
+
+### Fixed
+
+- Fixed Boolean property rendering
+
+## [1.2.1] - 2022-11-20
+
+### Fixed
+
+- Fixed build issues
+
+## [1.2.0] - 2022-11-10
+
+### Added
+
+- Added foldout group feature
+
+## [1.1.0] - 2022-11-06
+
+### Added
+
+- Added field expansion prefixes
+
diff --git a/CHANGELOG.md.meta b/CHANGELOG.md.meta
new file mode 100644
index 0000000..94efe5a
--- /dev/null
+++ b/CHANGELOG.md.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 0b43f287dfebc55498b9072da3a69a2c
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/ShaderGraphEditor/OpenGraphGUIEditor.cs b/Editor/ShaderGraphEditor/OpenGraphGUIEditor.cs
index fdd4287..0e26280 100644
--- a/Editor/ShaderGraphEditor/OpenGraphGUIEditor.cs
+++ b/Editor/ShaderGraphEditor/OpenGraphGUIEditor.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
+using UnityEngine.UIElements;
///
/// This is a globally accessible "wrapper" class that helps
@@ -32,6 +33,10 @@ public class OpenGraphGUIEditor : ShaderGUI
///
const float texFieldBoxSize = 65f;
///
+ /// Width of vector field on Vec2 and Vec3 property renders.
+ ///
+ const float vecFieldBoxSize = 220f;
+ ///
/// Heuristic for when extra field shrinking kicks in on small inspectors.
///
const float minLabelWidthAdjustField = 320f;
@@ -70,6 +75,9 @@ public class OpenGraphGUIEditor : ShaderGUI
const string singleLineTexPrefix = "%";
const string dependentVisibleTextPrefix = "^";
const string linkedPropertyPrefix = "&";
+ const string vec2Prefix = "2~";
+ const string vec3Prefix = "3~";
+ const string vec4Prefix = "4~";
///
/// Representation of a property with the linkedPropertyPrefix.
@@ -175,7 +183,6 @@ void RenderPropertiesList(MaterialProperty[] properties)
else if (thisProp.displayName.StartsWith(foldoutPrefix))
{
//This is a foldout property
-
foldoutCount++;
}
}
@@ -194,7 +201,7 @@ void RenderPropertiesList(MaterialProperty[] properties)
continue;
}
- //First check if this property has a custom extension
+ //Check if this property has a custom extension
if(renderExtensions != null && renderExtensions.ContainsKey(thisProp.displayName))
{
//Invoke the custom render function passed into the dictionary
@@ -226,7 +233,7 @@ void RenderPropertiesList(MaterialProperty[] properties)
//Use min field width and don't render this property
SetFieldExpandedMode(false);
}
- else if(currentLinkedProperties.ContainsKey(propName) && DoRenderProp())
+ else if(currentLinkedProperties.ContainsKey(propName) && DoRenderFoldoutProp())
{
//This is a linked property, so check if it was rendered already
var thisLinkedProp = currentLinkedProperties[propName];
@@ -288,7 +295,7 @@ void RenderPropertiesList(MaterialProperty[] properties)
}
}
- else if(propName.StartsWith(labelPrefix) && DoRenderProp())
+ else if(propName.StartsWith(labelPrefix) && DoRenderFoldoutProp())
{
//This is a label type, so show a bold header instead of the property
@@ -297,7 +304,7 @@ void RenderPropertiesList(MaterialProperty[] properties)
RenderLabelProperty(propName);
}
- else if (propName.StartsWith(dependentVisibleTextPrefix) && DoRenderProp())
+ else if (propName.StartsWith(dependentVisibleTextPrefix) && DoRenderFoldoutProp())
{
//It is dependent, so we will conditionally render it
@@ -313,7 +320,7 @@ void RenderPropertiesList(MaterialProperty[] properties)
//Don't render this property
}
}
- else if (DoRenderProp())
+ else if (DoRenderFoldoutProp())
{
//It's not dependent, so update populated state based on this
if (thisProp.type == MaterialProperty.PropType.Texture)
@@ -403,6 +410,8 @@ void RenderDependentVisibleProperty(MaterialProperty v, string labelName, int in
///
void RenderVisibleProperty(MaterialProperty v, string labelName, int index)
{
+ bool lastMixedValue = EditorGUI.showMixedValue;
+ EditorGUI.showMixedValue = v.hasMixedValue;
if (labelName.StartsWith(singleLineTexPrefix))
{
@@ -439,7 +448,67 @@ void RenderVisibleProperty(MaterialProperty v, string labelName, int index)
{
//Labeled as a single line tex type, but not a texture
GraphLog("Property was labeled as a single line texture (" + singleLineTexPrefix
- + "), but not a texture type - " + labelName);
+ + "), but not a Texture type - " + labelName);
+ RenderDefaultPropertyView(v, labelName);
+ }
+ }
+ else if(labelName.StartsWith(vec2Prefix) || labelName.StartsWith(vec3Prefix) || labelName.StartsWith(vec4Prefix))
+ {
+ if(v.type == MaterialProperty.PropType.Vector)
+ {
+ //This is a vector type
+
+ int vecCount = 2;
+ string thisPrefix = vec2Prefix;
+ if(labelName.StartsWith(vec3Prefix))
+ {
+ vecCount = 3;
+ thisPrefix = vec3Prefix;
+ }
+ else if (labelName.StartsWith(vec4Prefix))
+ {
+ vecCount = 4;
+ thisPrefix = vec4Prefix;
+ }
+
+ //Trim the vector prefix
+ labelName = labelName.Substring(thisPrefix.Length);
+
+ if(vecCount == 4)
+ {
+ RenderDefaultPropertyView(v, labelName);
+ }
+ else
+ {
+ //Render custom vector fields
+
+ //Set the label width for vectors
+ var lastLabelWidth = EditorGUIUtility.labelWidth;
+ EditorGUIUtility.labelWidth = 0f;
+
+ EditorGUI.BeginChangeCheck();
+ Vector4 vec;
+ if(vecCount == 3)
+ {
+ vec = EditorGUILayout.Vector3Field(labelName, v.vectorValue, GUILayout.ExpandWidth(true));
+ }
+ else
+ {
+ vec = EditorGUILayout.Vector2Field(labelName, v.vectorValue, GUILayout.ExpandWidth(true));
+ }
+ if (EditorGUI.EndChangeCheck())
+ {
+ v.vectorValue = vec;
+ }
+
+ EditorGUIUtility.labelWidth = lastLabelWidth;
+ }
+ }
+ else
+ {
+ //Labeled as a vector but not one
+ GraphLog("Property was labeled as a Vector (" + vec2Prefix + " or " + vec3Prefix + " or " + vec4Prefix
+ + "), but was not a Vector type - " + labelName);
RenderDefaultPropertyView(v, labelName);
}
}
@@ -447,6 +516,8 @@ void RenderVisibleProperty(MaterialProperty v, string labelName, int index)
{
RenderDefaultPropertyView(v, labelName);
}
+
+ EditorGUI.showMixedValue = lastMixedValue;
}
///
@@ -458,6 +529,7 @@ void RenderDefaultPropertyView(MaterialProperty v, string customName = "")
string finalName = (customName == "") ? v.displayName : customName;
+ //Note: May want to check ShaderUtil.GetPropertyType for more complex fields
switch(v.type)
{
case MaterialProperty.PropType.Texture:
@@ -477,7 +549,7 @@ void RenderDefaultPropertyView(MaterialProperty v, string customName = "")
EditorGUIUtility.labelWidth = lastLabel;
break;
default:
- matEditor.DefaultShaderProperty(v, finalName);
+ matEditor.ShaderProperty(v, finalName);
break;
}
@@ -501,7 +573,7 @@ void RenderLabelProperty(string propName)
/// based on foldout status.
///
///
- bool DoRenderProp()
+ bool DoRenderFoldoutProp()
{
return (!currentlyInFoldout || foldoutArray[currentFoldoutIndex]);
}
diff --git a/README.md b/README.md
index 786f0d6..329e5fb 100644
--- a/README.md
+++ b/README.md
@@ -17,9 +17,9 @@ The default Inspector view for ShaderGraph-based materials can be somewhat bland
If you're looking for a more comprehensive and feature-complete Shader GUI package, I highly recommend [Shader Graph Markdown](https://assetstore.unity.com/packages/tools/gui/shader-graph-markdown-194781) which this project is inspired from. They will be able to provide much more support and QOL features for developers needing extensive custom GUIs. The intent of OpenGraphGUI is to provide a simple open source alternative that the community is free to edit and improve as needed.
-### Match the look of URP Lit Materials
+### Match the look of built-in URP Materials
-**OpenGraphGUI** was built to be a replacement for the default ShaderGraph GUI provided by Unity. The feature set allows you to add in features such as the "Single Line Texture" that you'd find in default URP materials. It also provides labels and other "clean up" enhancements to give you more control over the look of your GUI.
+**OpenGraphGUI** was built to be a replacement for the default ShaderGraph GUI provided by Unity. The feature set allows you to add cleaner layouts for your material properties such as the "Single Line Texture" that you'd find in default URP materials. It also provides labels and other organizational enhancements to give you more control over the look of your GUI.
## Usage
@@ -29,30 +29,36 @@ In ShaderGraph, simply change your *"Custom Editor GUI"* setting to the named cl
### Labels & Alignment
-Prefix one of your properties with the **star symbol (\*)** and that field will become a bold label.
+> Use these naming rules to adjust the spacing of your Material's inspector and organize fields. Note that these properties are only meant to send information to OpenGraphGUI and will not be rendered, so you can use any type you prefer. For consistency, choosing a Boolean for these properties is simplest.
-Use a property called **\[Centered\]** to adjust the spacing of the Inspector fields to match the look of non-ShaderGraph default materials. Use a property called **\[RightBound\]** to return the field spacing to the default ShaderGraph look.
+Prefix one of your property names with the **star symbol (\*)** and that field will become a bold label. For example, if you want a bold label with the text **"Lighting"**, use the name `*Lighting` for that property in ShaderGraph.
+
+Create a property with the name **\[Centered\]** to adjust the spacing of the Inspector fields to match the look of non-ShaderGraph default materials. Use a property called **\[RightBound\]** to return the field spacing to the default ShaderGraph look.
-**New!** When in the **\[Centered\]** mode, use a property called **\[MaxField\]** to let the field take up more width in the inspector. This look is meant to match the "expanded" feel of color tints for single-line textures and improve the accessibility of fields by making them easier to edit. Use a property called **\[MinField\]** to return to the small field style.
+When in the **\[Centered\]** mode, use a property called **\[MaxField\]** to let the value field take up more width in the inspector. This look is meant to match the "expanded" feel of color tints for single-line textures and improve the accessibility of fields by making them easier to edit. Use a property called **\[MinField\]** to return to the default spacing style.
-**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.
+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. Each subsequent property will become a part of the group. You can create up to 128 unique foldout groups by labeling 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.
+> Use these naming rules to adjust how each field is rendered in the inspector.
+
+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. Example name: `%MySingleLineTexture`
-Follow up a single-line texture property with an **ampersand prefix (&)** and the resulting property will be drawn on the same line as the texture. OpenGraphGUI calls this a "linked property", and you'll commonly find these used as "tint colors" in the default materials.
+Follow up a single-line texture property with a property that uses the **ampersand prefix (&)** and the resulting property will be shown on the same line as the texture. OpenGraphGUI calls this a "linked property", and you'll commonly find these used as "tint colors" in the default materials. Example name: `&MyLinkedProperty`
-Follow up any texture property with an **arrow prefix (^)** and that property will only become visible when the texture above it has been filled out by the user (not null). This is called a "dependent visible" property. You'll find this on many custom shaders that utilize a strength value, appearing only when the asociated texture is present.
+Follow up any texture property with a property that uses the **arrow prefix (^)** and that property will only become visible when the texture above it has been populated by the user (not null). This is called a "dependent visible" property. You'll find this on many custom shaders that utilize a strength value, appearing only when the asociated texture is present. Example name: `^MyDependentProperty`
+**NEW!** Prefix any vector property with **2~**, **3~**, or **4~** to show it as a Vector2, Vector3, or Vector4 field respectively. By default, ShaderGraph material inspectors render all vectors as Vector4, so this extra information is necessary to tell OpenGraphGUI which type you want to use. Example name: `2~MyVector2` or `3~MyVector3`
+
### Extensions
**OpenGraphGUI** also supports custom property extensions if you'd like to keep the ease of use of prefixing without re-writing the whole package.
@@ -72,7 +78,7 @@ public MyOpenGraphGUIExtension()
Finally, set the *Custom Editor GUI* of your ShaderGraph to your custom class. That's it! Now you've got a custom function to render the property of your choice which is used in place of the drawing code that OpenGraphGUI would've used once it finds that property.
-## Installation
+## Recommended Installation
1. Open the [Package Manager](https://docs.unity3d.com/2020.3/Documentation/Manual/upm-ui.html) in Unity
2. Click the '+' icon and hit *"Add package from git URL"*
@@ -80,10 +86,14 @@ Finally, set the *Custom Editor GUI* of your ShaderGraph to your custom class. T
4. Wait for download to complete
5. Add the custom GUI class *RPOpenGraphGUI* to the *Custom Editor GUI* field in your ShaderGraph of choice
-If installation fails due to version requirements, you may be able force OpenGraphGUI to work by downloading the project as .zip and editing the "package.json" file to lower the Unity requirement. Deleting the .meta files may also be necessary and shouldn't break anything... I think. Then use the *"Add package from disk"* option to add your custom version instead.
-
If you're looking to add a specific release of OpenGraphGUI, you can specify a release tag with the hashtag like so: "https://github.com/RobProductions/OpenGraphGUI.git#ReleaseNumber"
+## Manual Installation
+
+You can also manually install OpenGraphGUI by downloading the project as .zip and placing the contents into your *Assets* folder or into the *Packages* folder to create an embedded package. I don't recommend going this route unless you have specific reason to keep a static local copy.
+
+If the Package Manager installation fails due to version requirements, you may be able force OpenGraphGUI to work by downloading the project as .zip and editing the "package.json" file to lower the Unity requirement. Deleting the .meta files may also be necessary and shouldn't break anything... I think. Then use the *"Add package from disk"* option to add your custom version instead.
+
## How to Contribute
This open source project is free for all to suggest improvements, and I'm hoping that more contributors could help clean up the code and add further features as suggested by the community. These are the recommended steps to add your contribution:
@@ -108,7 +118,7 @@ In theory **OpenGraphGUI** should work with regular Shaders and even HDRP Shader
### Limitations
- Though there shouldn't be any performance concerns with the prefixing approach (Unity should automatically cull out properties internally that are not used), it does bloat up the ShaderGraph quite a bit. Since this is meant to be a simple enhancement, I didn't take the route of editing the ShaderGraph GUI itself, so prefixed properties won't look any different from non-prefixed ones.
-- There are certain rules you must follow for your properties to show up as expected. All linked properties must follow a single line texture property. Dependent visible properties must follow another dependent visible or texture property or linked property (since it will be bundled with the texture). If those rules are violated, OpenGraphGUI will throw a warning to the console.
+- There are certain rules you must follow for your properties to show up as expected. All linked properties must follow a single line texture property. Dependent visible properties must follow another dependent visible property, a texture property, or a linked property (since it will be bundled with the texture). If those rules are violated, OpenGraphGUI will throw a warning to the console with some specifics about what went wrong.
### License
diff --git a/package.json b/package.json
index 9f8a748..617492b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "com.robproductions.opengraphgui",
- "version": "1.2.1",
+ "version": "1.3.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",
@@ -9,9 +9,9 @@
"license": "MIT License",
"keywords": [
"shader",
- "graph",
- "editor",
- "gui"
+ "graph",
+ "editor",
+ "gui"
],
"author": {
"name": "RobProductions",