Added new KeywordEnumTypeDrawer;

Added new method to use generic to add ui scope
This commit is contained in:
2025-08-17 13:01:40 +09:00
parent 86f0bf639c
commit 8250bc128d
9 changed files with 143 additions and 6 deletions

View File

@@ -7,7 +7,11 @@ namespace Misaki.ShaderGUI
{
public void AddUIScope(IMaterialUIScope scope);
public T GetUIScope<T>() where T : class, IMaterialUIScope;
public void AddUIScope<T>()
where T : IMaterialUIScope, new();
public T GetUIScope<T>()
where T : IMaterialUIScope;
public void Initialize(MaterialEditor materialEditor, MaterialProperty[] properties);

View File

@@ -0,0 +1,6 @@
namespace Misaki.ShaderGUI
{
public static class MaterialHelper
{
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: bcf12ee4f77a09b49820a65e2eb5574e

View File

@@ -32,7 +32,7 @@ namespace Misaki.ShaderGUI
public MaterialEditor Editor => editor;
public abstract void LoadMaterialProperties();
protected abstract void LoadMaterialProperties();
protected abstract void DrawContent();

View File

@@ -28,7 +28,7 @@ namespace Misaki.ShaderGUI
{
if (!IsPropertyTypeSuitable(prop))
{
var c = EditorGUIUtility.TrTempContent("Toggle used on a non-float property: " + prop.name);
var c = EditorGUIUtility.TrTempContent($"Enum flags used on a property {prop.name} with unsupported type: {prop.propertyType}");
EditorGUI.LabelField(position, c, EditorStyles.helpBox);
return;
}

View File

@@ -0,0 +1,115 @@
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
namespace Misaki.ShaderGUI
{
public class KeywordEnumTypeDrawer : MaterialPropertyDrawer
{
private readonly Type enumType;
public KeywordEnumTypeDrawer(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.Int;
#endif
}
private static string GetKeywordName(MaterialProperty prop, Enum enumValue)
{
var keyword = prop.name.ToUpper() + '_' + enumValue.ToString().ToUpper();
return keyword;
}
private void OnPropertyChanged(MaterialProperty prop)
{
var values = Enum.GetValues(enumType);
foreach (var mat in prop.targets)
{
if (mat is not Material material)
{
continue;
}
#if UNITY_6000_1_OR_NEWER
var valueIndex = prop.propertyType == ShaderPropertyType.Int ? prop.intValue : (int)prop.floatValue;
#else
var valueIndex = prop.type == MaterialProperty.PropType.Int ? prop.intValue : (int)prop.floatValue;
#endif
for (var i = 0; i < values.Length; i++)
{
var keywordName = GetKeywordName(prop, (Enum)Enum.ToObject(enumType, i));
if (i == valueIndex)
{
material.EnableKeyword(keywordName);
}
else
{
material.DisableKeyword(keywordName);
}
}
}
}
public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor)
{
if (!IsPropertyTypeSuitable(prop))
{
var c = EditorGUIUtility.TrTempContent(($"Keyword enum type used on a property {prop.name} with unsupported type: {prop.propertyType}"));
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.EnumPopup(position, label, (Enum)Enum.ToObject(enumType, value));
value = Convert.ToInt32(enumValue);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck())
{
prop.floatValue = value;
OnPropertyChanged(prop);
}
}
else
{
EditorGUI.BeginChangeCheck();
var value = prop.intValue;
EditorGUI.showMixedValue = prop.hasMixedValue;
var enumValue = EditorGUI.EnumPopup(position, label, (Enum)Enum.ToObject(enumType, value));
value = Convert.ToInt32(enumValue);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck())
{
prop.intValue = value;
OnPropertyChanged(prop);
}
}
MaterialEditor.EndProperty();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: cc930296c99db9847b93eb6ed4b6df87

View File

@@ -15,9 +15,17 @@ namespace Misaki.ShaderGUI
_scopes.Add(scope);
}
public T GetUIScope<T>() where T : class, IMaterialUIScope
public void AddUIScope<T>()
where T : IMaterialUIScope, new()
{
return _scopes.Find(s => s is T) as T;
var scope = new T();
_scopes.Add(scope);
}
public T GetUIScope<T>()
where T : IMaterialUIScope
{
return (T)_scopes.Find(s => s is T);
}
public void Initialize(MaterialEditor materialEditor, MaterialProperty[] properties)