diff --git a/Editor/Helpers/MaterialEditorHelpers.cs b/Editor/Helpers/MaterialEditorHelpers.cs
index cd03aa1..4b9df8d 100644
--- a/Editor/Helpers/MaterialEditorHelpers.cs
+++ b/Editor/Helpers/MaterialEditorHelpers.cs
@@ -81,9 +81,9 @@ namespace Misaki.ShaderGUI
/// The label of the texture property.
/// The texture property to draw.
/// True if the texture property is not null. Otherwise, false.
- public static bool KeywordTexturePropertySingleLine(this MaterialEditor editor, GUIContent label, MaterialProperty textureProperty)
+ public static bool KeywordTexturePropertySingleLine(this MaterialEditor editor, GUIContent label, MaterialProperty textureProperty, string keywordName = null)
{
- return KeywordTexturePropertySingleLine(editor, label, textureProperty, null, null);
+ return KeywordTexturePropertySingleLine(editor, label, textureProperty, null, null, keywordName);
}
///
@@ -94,9 +94,9 @@ namespace Misaki.ShaderGUI
/// The texture property to draw.
/// The first extra property to draw.
/// True if the texture property is not null. Otherwise, false.
- public static bool KeywordTexturePropertySingleLine(this MaterialEditor editor, GUIContent label, MaterialProperty textureProperty, MaterialProperty extraProperty)
+ public static bool KeywordTexturePropertySingleLine(this MaterialEditor editor, GUIContent label, MaterialProperty textureProperty, MaterialProperty extraProperty, string keywordName = null)
{
- return KeywordTexturePropertySingleLine(editor, label, textureProperty, extraProperty, null);
+ return KeywordTexturePropertySingleLine(editor, label, textureProperty, extraProperty, null, keywordName);
}
///
@@ -108,13 +108,13 @@ namespace Misaki.ShaderGUI
/// The first extra property to draw.
/// The second extra property to draw.
/// True if the texture property is not null. Otherwise, false.
- public static bool KeywordTexturePropertySingleLine(this MaterialEditor editor, GUIContent label, MaterialProperty textureProperty, MaterialProperty extraProperty1, MaterialProperty extraProperty2)
+ public static bool KeywordTexturePropertySingleLine(this MaterialEditor editor, GUIContent label, MaterialProperty textureProperty, MaterialProperty extraProperty1, MaterialProperty extraProperty2, string keywordName = null)
{
EditorGUI.BeginChangeCheck();
editor.TexturePropertySingleLine(label, textureProperty, extraProperty1, extraProperty2);
if (EditorGUI.EndChangeCheck())
{
- editor.SetKeyword(textureProperty.name.ToUpper(), textureProperty.textureValue != null);
+ editor.SetKeyword(string.IsNullOrEmpty(keywordName) ? textureProperty.name.ToUpper() : keywordName, textureProperty.textureValue != null);
}
return textureProperty.textureValue != null;
diff --git a/Editor/Helpers/MaterialPropertyHelpers.cs b/Editor/Helpers/MaterialPropertyHelpers.cs
index 6de4f81..f7c708c 100644
--- a/Editor/Helpers/MaterialPropertyHelpers.cs
+++ b/Editor/Helpers/MaterialPropertyHelpers.cs
@@ -28,5 +28,28 @@ namespace Misaki.ShaderGUI
throw new NotSupportedException("Property type is not supported.");
}
+
+ public static T GetEnumValue(this MaterialProperty materialProperty) where T : Enum
+ {
+#if UNITY_6000_1_OR_NEWER
+ if (materialProperty.propertyType == UnityEngine.Rendering.ShaderPropertyType.Float || materialProperty.propertyType == UnityEngine.Rendering.ShaderPropertyType.Range)
+#else
+ if (materialProperty.type == MaterialProperty.PropType.Float || materialProperty.type == MaterialProperty.PropType.Range)
+#endif
+ {
+ return (T)Enum.ToObject(typeof(T), (int)materialProperty.floatValue);
+ }
+
+#if UNITY_6000_1_OR_NEWER
+ if (materialProperty.propertyType == UnityEngine.Rendering.ShaderPropertyType.Int)
+#else
+ if (materialProperty.type == MaterialProperty.PropType.Int)
+#endif
+ {
+ return (T)Enum.ToObject(typeof(T), materialProperty.intValue);
+ }
+
+ throw new NotSupportedException("Property type is not supported.");
+ }
}
}
\ No newline at end of file
diff --git a/Editor/MaterialUIBlock.cs b/Editor/MaterialUIBlock.cs
index 92cdeeb..7d9bb1d 100644
--- a/Editor/MaterialUIBlock.cs
+++ b/Editor/MaterialUIBlock.cs
@@ -8,7 +8,7 @@ namespace Misaki.ShaderGUI.Packages
{
public abstract class MaterialUIBlock : IMaterialUIScope where TExpandableBit : Enum, IConvertible
{
- private readonly MaterialPropertyContainer _propertyContainer = new();
+ protected readonly MaterialPropertyContainer propertyContainer = new();
protected MaterialEditor editor;
protected IMaterialUIScopeContainer owner;
@@ -39,13 +39,13 @@ namespace Misaki.ShaderGUI.Packages
editor = materialEditor;
owner = container;
- LoadMaterialProperties(_propertyContainer);
+ LoadMaterialProperties(propertyContainer);
UpdateMaterialProperties(properties);
}
public void UpdateMaterialProperties(IEnumerable properties)
{
- _propertyContainer.ReloadProperties(properties);
+ propertyContainer.ReloadProperties(properties);
}
public void Draw()
diff --git a/Editor/PropertyDrawer/EnumFlagsDrawer.cs b/Editor/PropertyDrawer/EnumFlagsDrawer.cs
new file mode 100644
index 0000000..0b53c49
--- /dev/null
+++ b/Editor/PropertyDrawer/EnumFlagsDrawer.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Reflection;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.Rendering;
+
+namespace Misaki.ShaderGUI
+{
+ public class EnumFlagsUIDrawer : MaterialPropertyDrawer
+ {
+ private readonly Type enumType;
+
+ public EnumFlagsUIDrawer(string enumTypeName, string assemblyName)
+ {
+ enumType = Type.GetType(Assembly.CreateQualifiedName(assemblyName, enumTypeName), true);
+ }
+
+ private static bool IsPropertyTypeSuitable(MaterialProperty prop)
+ {
+#if UNITY_6000_1_OR_NEWER
+ return prop.propertyType == ShaderPropertyType.Float || prop.propertyType == ShaderPropertyType.Range || prop.propertyType == ShaderPropertyType.Int;
+#else
+ return prop.type == MaterialProperty.PropType.Float || prop.type == MaterialProperty.PropType.Range || prop.type == MaterialProperty.PropType.Float;
+#endif
+ }
+
+ public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor)
+ {
+ if (!IsPropertyTypeSuitable(prop))
+ {
+ var c = EditorGUIUtility.TrTempContent("Toggle used on a non-float property: " + prop.name);
+ EditorGUI.LabelField(position, c, EditorStyles.helpBox);
+ return;
+ }
+
+ MaterialEditor.BeginProperty(position, prop);
+
+#if UNITY_6000_1_OR_NEWER
+ if (prop.propertyType != ShaderPropertyType.Int)
+#else
+ if (prop.type != MaterialProperty.PropType.Int)
+#endif
+ {
+ EditorGUI.BeginChangeCheck();
+
+ var value = (int)prop.floatValue;
+ EditorGUI.showMixedValue = prop.hasMixedValue;
+ var enumValue = EditorGUI.EnumFlagsField(position, label, (Enum)Enum.ToObject(enumType, value));
+ value = Convert.ToInt32(enumValue);
+ EditorGUI.showMixedValue = false;
+
+ if (EditorGUI.EndChangeCheck())
+ {
+ prop.floatValue = value;
+ }
+ }
+ else
+ {
+ EditorGUI.BeginChangeCheck();
+
+ var value = prop.intValue;
+ EditorGUI.showMixedValue = prop.hasMixedValue;
+ var enumValue = EditorGUI.EnumFlagsField(position, label, (Enum)Enum.ToObject(enumType, value));
+ value = Convert.ToInt32(enumValue);
+
+ EditorGUI.showMixedValue = false;
+ if (EditorGUI.EndChangeCheck())
+ {
+ prop.intValue = value;
+ }
+ }
+
+ MaterialEditor.EndProperty();
+ }
+ }
+}
diff --git a/Editor/PropertyDrawer/EnumFlagsDrawer.cs.meta b/Editor/PropertyDrawer/EnumFlagsDrawer.cs.meta
new file mode 100644
index 0000000..4c94482
--- /dev/null
+++ b/Editor/PropertyDrawer/EnumFlagsDrawer.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 44cf7877640af1d4795a4d087824f9f5
\ No newline at end of file
diff --git a/Editor/PropertyDrawer/PopupDrawer.cs b/Editor/PropertyDrawer/PopupDrawer.cs
index 4df43c1..4695ada 100644
--- a/Editor/PropertyDrawer/PopupDrawer.cs
+++ b/Editor/PropertyDrawer/PopupDrawer.cs
@@ -9,11 +9,11 @@ namespace Misaki.ShaderGUI
{
private static readonly GUIContent[] _options = { new("Disabled"), new("Enabled") };
- protected virtual void SetKeyword(MaterialProperty prop, bool on)
+ protected virtual void OnPropertyChange(MaterialProperty prop)
{
}
- static bool IsPropertyTypeSuitable(MaterialProperty prop)
+ private static bool IsPropertyTypeSuitable(MaterialProperty prop)
{
#if UNITY_6000_1_OR_NEWER
return prop.propertyType == ShaderPropertyType.Float || prop.propertyType == ShaderPropertyType.Range || prop.propertyType == ShaderPropertyType.Int;
@@ -41,14 +41,14 @@ namespace Misaki.ShaderGUI
{
EditorGUI.BeginChangeCheck();
- var value = (int)Math.Abs(prop.floatValue);
+ var value = (int)Mathf.Abs(prop.floatValue);
EditorGUI.showMixedValue = prop.hasMixedValue;
value = EditorGUI.Popup(position, label, value, _options);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck())
{
prop.floatValue = value;
- SetKeyword(prop, value != 0);
+ OnPropertyChange(prop);
}
}
else
@@ -62,7 +62,7 @@ namespace Misaki.ShaderGUI
if (EditorGUI.EndChangeCheck())
{
prop.intValue = value;
- SetKeyword(prop, value != 0);
+ OnPropertyChange(prop);
}
}
@@ -74,7 +74,7 @@ namespace Misaki.ShaderGUI
{
private const string Keyword_Suffix = "_ON";
- protected override void SetKeyword(MaterialProperty prop, bool on)
+ protected override void OnPropertyChange(MaterialProperty prop)
{
var keywordName = prop.name.ToUpper() + Keyword_Suffix;
foreach (var target in prop.targets)
@@ -84,7 +84,52 @@ namespace Misaki.ShaderGUI
continue;
}
- material.SetKeyword(new LocalKeyword(material.shader, keywordName), on);
+#if UNITY_6000_1_OR_NEWER
+ if (prop.propertyType != ShaderPropertyType.Int)
+#else
+ if (prop.type != MaterialProperty.PropType.Int)
+#endif
+ {
+ material.SetKeyword(new LocalKeyword(material.shader, keywordName), prop.floatValue != 0);
+ }
+ else
+ {
+ material.SetKeyword(new LocalKeyword(material.shader, keywordName), prop.intValue != 0);
+ }
+ }
+ }
+ }
+
+ public class PassPopupDrawer : PopupUIDrawer
+ {
+ private readonly string _passName;
+
+ public PassPopupDrawer(string passName)
+ {
+ _passName = passName;
+ }
+
+ protected override void OnPropertyChange(MaterialProperty prop)
+ {
+ foreach (var target in prop.targets)
+ {
+ if (target is not Material material)
+ {
+ continue;
+ }
+
+#if UNITY_6000_1_OR_NEWER
+ if (prop.propertyType != ShaderPropertyType.Int)
+#else
+ if (prop.type != MaterialProperty.PropType.Int)
+#endif
+ {
+ material.SetShaderPassEnabled(_passName, prop.floatValue != 0);
+ }
+ else
+ {
+ material.SetShaderPassEnabled(_passName, prop.intValue != 0);
+ }
}
}
}