Skip to content

Commit

Permalink
Merge pull request #8 from RobProductions/working-branch
Browse files Browse the repository at this point in the history
Fix Booleans and Add Vector Prefixes
  • Loading branch information
RobProductions authored Dec 14, 2023
2 parents b09d6d0 + 1cd73b9 commit 0d79d1e
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 26 deletions.
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

7 changes: 7 additions & 0 deletions CHANGELOG.md.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 81 additions & 9 deletions Editor/ShaderGraphEditor/OpenGraphGUIEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UIElements;

/// <summary>
/// This is a globally accessible "wrapper" class that helps
Expand Down Expand Up @@ -32,6 +33,10 @@ public class OpenGraphGUIEditor : ShaderGUI
/// </summary>
const float texFieldBoxSize = 65f;
/// <summary>
/// Width of vector field on Vec2 and Vec3 property renders.
/// </summary>
const float vecFieldBoxSize = 220f;
/// <summary>
/// Heuristic for when extra field shrinking kicks in on small inspectors.
/// </summary>
const float minLabelWidthAdjustField = 320f;
Expand Down Expand Up @@ -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~";

/// <summary>
/// Representation of a property with the linkedPropertyPrefix.
Expand Down Expand Up @@ -175,7 +183,6 @@ void RenderPropertiesList(MaterialProperty[] properties)
else if (thisProp.displayName.StartsWith(foldoutPrefix))
{
//This is a foldout property

foldoutCount++;
}
}
Expand All @@ -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
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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

Expand All @@ -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

Expand All @@ -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)
Expand Down Expand Up @@ -403,6 +410,8 @@ void RenderDependentVisibleProperty(MaterialProperty v, string labelName, int in
/// <param name="index"></param>
void RenderVisibleProperty(MaterialProperty v, string labelName, int index)
{
bool lastMixedValue = EditorGUI.showMixedValue;
EditorGUI.showMixedValue = v.hasMixedValue;

if (labelName.StartsWith(singleLineTexPrefix))
{
Expand Down Expand Up @@ -439,14 +448,76 @@ 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);
}
}
else
{
RenderDefaultPropertyView(v, labelName);
}

EditorGUI.showMixedValue = lastMixedValue;
}

/// <summary>
Expand All @@ -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:
Expand All @@ -477,7 +549,7 @@ void RenderDefaultPropertyView(MaterialProperty v, string customName = "")
EditorGUIUtility.labelWidth = lastLabel;
break;
default:
matEditor.DefaultShaderProperty(v, finalName);
matEditor.ShaderProperty(v, finalName);
break;
}

Expand All @@ -501,7 +573,7 @@ void RenderLabelProperty(string propName)
/// based on foldout status.
/// </summary>
/// <returns></returns>
bool DoRenderProp()
bool DoRenderFoldoutProp()
{
return (!currentlyInFoldout || foldoutArray[currentFoldoutIndex]);
}
Expand Down
36 changes: 23 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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.

<img width = "800" src="Documentation~/DocAssets/AlignmentTags.gif">

**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.

<img width = "500" src="Documentation~/DocAssets/FieldWidthScreenshot.jpg">

**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.

<img width = "550" src="Documentation~/DocAssets/FoldoutGroupsScreenshot.jpg">

### 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`

<img width = "800" src="Documentation~/DocAssets/DependentTags.gif">

**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.
Expand All @@ -72,18 +78,22 @@ 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"*
3. Add the GitHub "HTTPS Clone" URL for OpenGraphGUI: [https://github.com/RobProductions/OpenGraphGUI.git](https://github.com/RobProductions/OpenGraphGUI.git)
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:
Expand All @@ -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

Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -9,9 +9,9 @@
"license": "MIT License",
"keywords": [
"shader",
"graph",
"editor",
"gui"
"graph",
"editor",
"gui"
],
"author": {
"name": "RobProductions",
Expand Down

0 comments on commit 0d79d1e

Please sign in to comment.