220 lines
11 KiB
C#
220 lines
11 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace EPOOutline
|
|
{
|
|
public static class SerializedPropertyExtentions
|
|
{
|
|
private static MethodInfo getFieldInfoAndStaticTypeFromProperty;
|
|
|
|
public static Attribute[] GetFieldAttributes(this SerializedProperty prop)
|
|
{
|
|
if (getFieldInfoAndStaticTypeFromProperty == null)
|
|
{
|
|
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
|
{
|
|
foreach (var t in assembly.GetTypes())
|
|
{
|
|
if (t.Name != "ScriptAttributeUtility")
|
|
continue;
|
|
|
|
getFieldInfoAndStaticTypeFromProperty = t.GetMethod("GetFieldAttributes", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
|
foreach (var info in getFieldInfoAndStaticTypeFromProperty.GetParameters())
|
|
Debug.Log(info.ParameterType + " " + info.Name);
|
|
|
|
break;
|
|
}
|
|
|
|
if (getFieldInfoAndStaticTypeFromProperty != null)
|
|
break;
|
|
}
|
|
}
|
|
|
|
var p = new object[] { prop, null };
|
|
var fieldInfo = getFieldInfoAndStaticTypeFromProperty.Invoke(null, p) as Attribute[];
|
|
return fieldInfo;
|
|
}
|
|
|
|
public static T GetCustomAttributeFromProperty<T>(this SerializedProperty prop) where T : System.Attribute
|
|
{
|
|
return Array.Find(GetFieldAttributes(prop), x => x is T) as T;
|
|
}
|
|
}
|
|
|
|
[CustomPropertyDrawer(typeof(SerializedPass))]
|
|
public class SerializedPassPropertyDrawer : PropertyDrawer
|
|
{
|
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
|
{
|
|
var drawingPosition = position;
|
|
drawingPosition.height = EditorGUIUtility.singleLineHeight;
|
|
|
|
var shaderProperty = property.FindPropertyRelative("shader");
|
|
|
|
var currentShaderReference = shaderProperty.objectReferenceValue as Shader;
|
|
|
|
var attribute = (SerializedPassInfoAttribute)null;// property.GetCustomAttributeFromProperty<SerializedPassInfoAttribute>();
|
|
|
|
var prefix = attribute == null ? "Hidden/EPO/Fill/" : attribute.ShadersFolder;
|
|
var fillLabel = currentShaderReference == null ? "none" : currentShaderReference.name.Substring(prefix.Length);
|
|
if (shaderProperty.hasMultipleDifferentValues)
|
|
fillLabel = "-";
|
|
|
|
if (EditorGUI.DropdownButton(position, new GUIContent(label.text + " : " + fillLabel), FocusType.Passive))
|
|
{
|
|
var menu = new GenericMenu();
|
|
|
|
menu.AddItem(new GUIContent("none"), currentShaderReference == null && !shaderProperty.hasMultipleDifferentValues, () =>
|
|
{
|
|
shaderProperty.objectReferenceValue = null;
|
|
shaderProperty.serializedObject.ApplyModifiedProperties();
|
|
});
|
|
|
|
var shaders = AssetDatabase.FindAssets("t:Shader");
|
|
foreach (var shader in shaders)
|
|
{
|
|
var loadedShader = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(shader), typeof(Shader)) as Shader;
|
|
if (!loadedShader.name.StartsWith(prefix))
|
|
continue;
|
|
|
|
menu.AddItem(new GUIContent(loadedShader.name.Substring(prefix.Length)), loadedShader == shaderProperty.objectReferenceValue && !shaderProperty.hasMultipleDifferentValues, () =>
|
|
{
|
|
shaderProperty.objectReferenceValue = loadedShader;
|
|
shaderProperty.serializedObject.ApplyModifiedProperties();
|
|
});
|
|
}
|
|
|
|
menu.ShowAsContext();
|
|
}
|
|
|
|
if (shaderProperty.hasMultipleDifferentValues)
|
|
return;
|
|
|
|
if (currentShaderReference != null)
|
|
{
|
|
position.x += EditorGUIUtility.singleLineHeight;
|
|
position.width -= EditorGUIUtility.singleLineHeight;
|
|
var properties = new Dictionary<string, SerializedProperty>();
|
|
|
|
var serializedProperties = property.FindPropertyRelative("serializedProperties");
|
|
|
|
for (var index = 0; index < serializedProperties.arraySize; index++)
|
|
{
|
|
var subProperty = serializedProperties.GetArrayElementAtIndex(index);
|
|
|
|
var propertyName = subProperty.FindPropertyRelative("PropertyName");
|
|
var propertyValue = subProperty.FindPropertyRelative("Property");
|
|
|
|
if (propertyName == null || propertyValue == null)
|
|
break;
|
|
|
|
properties.Add(propertyName.stringValue, propertyValue);
|
|
}
|
|
|
|
var fillParametersPosition = position;
|
|
fillParametersPosition.height = EditorGUIUtility.singleLineHeight;
|
|
for (var index = 0; index < ShaderUtil.GetPropertyCount(currentShaderReference); index++)
|
|
{
|
|
var propertyName = ShaderUtil.GetPropertyName(currentShaderReference, index);
|
|
if (!propertyName.StartsWith("_Public"))
|
|
continue;
|
|
|
|
fillParametersPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
|
|
|
SerializedProperty currentProperty;
|
|
if (!properties.TryGetValue(propertyName, out currentProperty))
|
|
{
|
|
serializedProperties.InsertArrayElementAtIndex(serializedProperties.arraySize);
|
|
currentProperty = serializedProperties.GetArrayElementAtIndex(serializedProperties.arraySize - 1);
|
|
currentProperty.FindPropertyRelative("PropertyName").stringValue = propertyName;
|
|
currentProperty = currentProperty.FindPropertyRelative("Property");
|
|
|
|
var tempMaterial = new Material(currentShaderReference);
|
|
|
|
switch (ShaderUtil.GetPropertyType(currentShaderReference, index))
|
|
{
|
|
case ShaderUtil.ShaderPropertyType.Color:
|
|
currentProperty.FindPropertyRelative("ColorValue").colorValue = tempMaterial.GetColor(propertyName);
|
|
break;
|
|
case ShaderUtil.ShaderPropertyType.Vector:
|
|
currentProperty.FindPropertyRelative("VectorValue").vector4Value = tempMaterial.GetVector(propertyName);
|
|
break;
|
|
case ShaderUtil.ShaderPropertyType.Float:
|
|
currentProperty.FindPropertyRelative("FloatValue").floatValue = tempMaterial.GetFloat(propertyName);
|
|
break;
|
|
case ShaderUtil.ShaderPropertyType.Range:
|
|
currentProperty.FindPropertyRelative("FloatValue").floatValue = tempMaterial.GetFloat(propertyName);
|
|
break;
|
|
case ShaderUtil.ShaderPropertyType.TexEnv:
|
|
currentProperty.FindPropertyRelative("TextureValue").objectReferenceValue = tempMaterial.GetTexture(propertyName);
|
|
break;
|
|
}
|
|
|
|
GameObject.DestroyImmediate(tempMaterial);
|
|
|
|
properties.Add(propertyName, currentProperty);
|
|
}
|
|
|
|
if (currentProperty == null)
|
|
continue;
|
|
|
|
var content = new GUIContent(ShaderUtil.GetPropertyDescription(currentShaderReference, index));
|
|
|
|
switch (ShaderUtil.GetPropertyType(currentShaderReference, index))
|
|
{
|
|
case ShaderUtil.ShaderPropertyType.Color:
|
|
var colorProperty = currentProperty.FindPropertyRelative("ColorValue");
|
|
colorProperty.colorValue = EditorGUI.ColorField(fillParametersPosition, content, colorProperty.colorValue, true, true, true);
|
|
break;
|
|
case ShaderUtil.ShaderPropertyType.Vector:
|
|
var vectorProperty = currentProperty.FindPropertyRelative("VectorValue");
|
|
vectorProperty.vector4Value = EditorGUI.Vector4Field(fillParametersPosition, content, vectorProperty.vector4Value);
|
|
break;
|
|
case ShaderUtil.ShaderPropertyType.Float:
|
|
EditorGUI.PropertyField(fillParametersPosition, currentProperty.FindPropertyRelative("FloatValue"), content);
|
|
break;
|
|
case ShaderUtil.ShaderPropertyType.Range:
|
|
var floatProperty = currentProperty.FindPropertyRelative("FloatValue");
|
|
floatProperty.floatValue = EditorGUI.Slider(fillParametersPosition, content, floatProperty.floatValue,
|
|
ShaderUtil.GetRangeLimits(currentShaderReference, index, 1),
|
|
ShaderUtil.GetRangeLimits(currentShaderReference, index, 2));
|
|
break;
|
|
case ShaderUtil.ShaderPropertyType.TexEnv:
|
|
EditorGUI.PropertyField(fillParametersPosition, currentProperty.FindPropertyRelative("TextureValue"), content);
|
|
break;
|
|
}
|
|
|
|
currentProperty.FindPropertyRelative("PropertyType").intValue = (int)ShaderUtil.GetPropertyType(currentShaderReference, index);
|
|
}
|
|
}
|
|
}
|
|
|
|
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
|
{
|
|
if (property.FindPropertyRelative("shader").hasMultipleDifferentValues)
|
|
return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
|
|
|
var shaderProperty = property.FindPropertyRelative("shader");
|
|
var currentShaderReference = shaderProperty.objectReferenceValue as Shader;
|
|
|
|
var additionalCount = 0;
|
|
if (currentShaderReference != null)
|
|
{
|
|
for (var index = 0; index < ShaderUtil.GetPropertyCount(currentShaderReference); index++)
|
|
{
|
|
var propertyName = ShaderUtil.GetPropertyName(currentShaderReference, index);
|
|
if (!propertyName.StartsWith("_Public"))
|
|
continue;
|
|
|
|
additionalCount++;
|
|
}
|
|
}
|
|
|
|
return (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing) * (additionalCount + 1);
|
|
}
|
|
}
|
|
} |