Skip to content

[Shader Graph] Fix Bug with Enum Keyword Reference Suffix #58

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.shadergraph/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Copied nodes are now pasted at the cursor location instead of slightly offset from their original location
- Error messages reported on Sub Graph output nodes for invalid previews now present clearer information, with documentation support.
- Updated legacy COLOR output semantic to SV_Target in pixel shader for compatibility with DXC
- Changed the `Reference Suffix` of Keyword Enum entries so that you cannot edit them, which ensures that material keywords compile properly.

### Fixed
- Edges no longer produce errors when you save a Shader Graph.
Expand Down
6 changes: 4 additions & 2 deletions com.unity.shadergraph/Documentation~/Keywords.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ In addition to the common parameters listed above, Boolean Keywords have the fol
## Enum Keywords
Enum Keywords can have two or more states, which you define in the **Entries** list. If you expose an Enum Keyword, the **Display Names** in its **Entries** list appear in a dropdown menu in the Material Inspector.

When you define an Enum Keyword, Shader Graph appends the entry’s **Reference Suffix** to the main **Reference** name to define each state. It uses the `{Reference}_{ReferenceSuffix}` pattern to define most entries, but be aware that it uses an `else` statement to select the last entry, which it regards as the off state.
When you define an Enum Keyword, Shader Graph appends a sanitized version of the **Entry Name** to the main **Reference** name to define each state. You can see the sanitized version of the **Entry Name** to the right, under **Reference Suffix**. Shader Graph uses the `{Reference}_{ReferenceSuffix}` pattern to define most entries, but be aware that it uses an `else` statement to select the last entry, which it regards as the off state.

Special characters such as `( )` or `! @` are not valid in the **Entry Name** of an Enum Keyword. Shader Graph converts invalid characters to underscores ( `_` ).

![](images/keywords_enum.png)

Expand All @@ -60,4 +62,4 @@ Built-in Keywords are always either Boolean or Enum Keywords, but they behave sl

All Built-in Keyword fields on the Blackboard are grayed out except for the **Default** field, which you can enable or disable to show the differences in Shader Graph previews. You also cannot expose Built-in Keywords in the Material Inspector.

![](images/keywords_built-in.png)
![](images/keywords_built-in.png)
4 changes: 2 additions & 2 deletions com.unity.shadergraph/Documentation~/images/keywords_enum.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ class BlackboardFieldKeywordView : BlackboardFieldView
private IMGUIContainer m_Container;
private int m_SelectedIndex;
private ShaderKeyword m_Keyword;
private static GUIStyle greyLabel;

public BlackboardFieldKeywordView(BlackboardField blackboardField, GraphData graph, ShaderInput input)
: base (blackboardField, graph, input)
{
greyLabel = new GUIStyle(EditorStyles.label);
greyLabel.normal = new GUIStyleState { textColor = Color.grey };
greyLabel.focused = new GUIStyleState { textColor = Color.grey };
greyLabel.hover = new GUIStyleState { textColor = Color.grey };
}

public override void BuildCustomFields(ShaderInput input)
Expand Down Expand Up @@ -132,9 +137,9 @@ private void AddCallbacks()
{
int indent = 14;
var displayRect = new Rect(rect.x + indent, rect.y, (rect.width - indent) / 2, rect.height);
EditorGUI.LabelField(displayRect, "Display Name");
EditorGUI.LabelField(displayRect, "Entry Name");
var referenceRect = new Rect((rect.x + indent) + (rect.width - indent) / 2, rect.y, (rect.width - indent) / 2, rect.height);
EditorGUI.LabelField(referenceRect, "Reference Suffix");
EditorGUI.LabelField(referenceRect, "Reference Suffix", m_Keyword.isBuiltIn ? EditorStyles.label : greyLabel);
};

// Draw Element
Expand All @@ -144,10 +149,11 @@ private void AddCallbacks()
EditorGUI.BeginChangeCheck();

var displayName = EditorGUI.DelayedTextField( new Rect(rect.x, rect.y, rect.width / 2, EditorGUIUtility.singleLineHeight), entry.displayName, EditorStyles.label);
var referenceName = EditorGUI.DelayedTextField( new Rect(rect.x + rect.width / 2, rect.y, rect.width / 2, EditorGUIUtility.singleLineHeight), entry.referenceName, EditorStyles.label);
var referenceName = EditorGUI.TextField( new Rect(rect.x + rect.width / 2, rect.y, rect.width / 2, EditorGUIUtility.singleLineHeight), entry.referenceName,
m_Keyword.isBuiltIn ? EditorStyles.label : greyLabel);

displayName = GetDuplicateSafeDisplayName(entry.id, displayName);
referenceName = GetDuplicateSafeReferenceName(entry.id, referenceName.ToUpper());
referenceName = GetDuplicateSafeReferenceName(entry.id, displayName.ToUpper());

if (EditorGUI.EndChangeCheck())
{
Expand Down Expand Up @@ -257,6 +263,7 @@ private void ReorderEntries(ReorderableList list)
public string GetDuplicateSafeDisplayName(int id, string name)
{
name = name.Trim();
name = Regex.Replace(name, @"(?:[^A-Za-z_0-9_\s])", "_");
var entryList = m_ReorderableList.list as List<KeywordEntry>;
return GraphUtil.SanitizeName(entryList.Where(p => p.id != id).Select(p => p.displayName), "{0} ({1})", name);
}
Expand Down