Files
zeling_v2/Assets/LWGUI-1.14.1/Editor/ReflectionHelper.cs

167 lines
7.4 KiB
C#

// Copyright (c) Jason Ma
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace LWGUI
{
public class ReflectionHelper
{
private static Assembly UnityEditor_Assembly = Assembly.GetAssembly(typeof(Editor));
#region MaterialPropertyHandler
private static Type MaterialPropertyHandler_Type = UnityEditor_Assembly.GetType("UnityEditor.MaterialPropertyHandler");
private static MethodInfo MaterialPropertyHandler_GetHandler_Method = MaterialPropertyHandler_Type.GetMethod("GetHandler", BindingFlags.Static | BindingFlags.NonPublic);
private static PropertyInfo MaterialPropertyHandler_PropertyDrawer_Property = MaterialPropertyHandler_Type.GetProperty("propertyDrawer");
private static FieldInfo MaterialPropertyHandler_DecoratorDrawers_Field = MaterialPropertyHandler_Type.GetField("m_DecoratorDrawers", BindingFlags.NonPublic | BindingFlags.Instance);
public static MaterialPropertyDrawer GetPropertyDrawer(Shader shader, MaterialProperty prop, out List<MaterialPropertyDrawer> decoratorDrawers)
{
decoratorDrawers = new List<MaterialPropertyDrawer>();
var handler = MaterialPropertyHandler_GetHandler_Method.Invoke(null, new System.Object[] { shader, prop.name });
if (handler != null && handler.GetType() == MaterialPropertyHandler_Type)
{
decoratorDrawers = MaterialPropertyHandler_DecoratorDrawers_Field.GetValue(handler) as List<MaterialPropertyDrawer>;
return MaterialPropertyHandler_PropertyDrawer_Property.GetValue(handler, null) as MaterialPropertyDrawer;
}
return null;
}
public static MaterialPropertyDrawer GetPropertyDrawer(Shader shader, MaterialProperty prop)
{
List<MaterialPropertyDrawer> decoratorDrawers;
return GetPropertyDrawer(shader, prop, out decoratorDrawers);
}
#endregion
#region MaterialEditor
private static Type MaterialEditor_Type = typeof(MaterialEditor);
private static MethodInfo MaterialEditor_DoPowerRangeProperty_Method = MaterialEditor_Type.GetMethod("DoPowerRangeProperty", BindingFlags.Static | BindingFlags.NonPublic);
private static MethodInfo MaterialEditor_DefaultShaderPropertyInternal_Method = MaterialEditor_Type.GetMethod("DefaultShaderPropertyInternal", BindingFlags.NonPublic | BindingFlags.Instance, null,
new []{typeof(Rect), typeof(MaterialProperty), typeof(GUIContent)}, null);
#if !UNITY_2019_2_OR_NEWER
private static FieldInfo MaterialEditor_CustomShaderGUI_Field = MaterialEditor_Type.GetField("m_CustomShaderGUI", BindingFlags.NonPublic | BindingFlags.Instance);
#endif
public static ShaderGUI GetCustomShaderGUI(MaterialEditor editor)
{
#if !UNITY_2019_2_OR_NEWER
return MaterialEditor_CustomShaderGUI_Field.GetValue(editor) as ShaderGUI;
#else
return editor.customShaderGUI;
#endif
}
public static float DoPowerRangeProperty(Rect position, MaterialProperty prop, GUIContent label, float power)
{
return (float)MaterialEditor_DoPowerRangeProperty_Method.Invoke(null, new System.Object[] { position, prop, label, power });
}
public static void DefaultShaderPropertyInternal(MaterialEditor editor, Rect position, MaterialProperty prop, GUIContent label)
{
MaterialEditor_DefaultShaderPropertyInternal_Method.Invoke(editor, new System.Object[] { position, prop, label });
}
#endregion
#region EditorUtility
private static Type EditorUtility_Type = typeof(EditorUtility);
private static MethodInfo EditorUtility_DisplayCustomMenuWithSeparators_Method = EditorUtility_Type.GetMethod("DisplayCustomMenuWithSeparators", BindingFlags.NonPublic | BindingFlags.Static, null,
new []{typeof(Rect), typeof(string[]), typeof(bool[]), typeof(bool[]), typeof(int[]), typeof(EditorUtility.SelectMenuItemFunction), typeof(object), typeof(bool)}, null);
public static void DisplayCustomMenuWithSeparators(
Rect position,
string[] options,
bool[] enabled,
bool[] separator,
int[] selected,
EditorUtility.SelectMenuItemFunction callback,
object userData = null,
bool showHotkey = false)
{
EditorUtility_DisplayCustomMenuWithSeparators_Method.Invoke(null, new System.Object[] { position, options, enabled, separator, selected, callback, userData, showHotkey });
}
#endregion
#region MaterialEnumDrawer
// UnityEditor.MaterialEnumDrawer(string enumName)
private static System.Type[] _types;
public static System.Type[] GetAllTypes()
{
if (_types == null)
{
_types = ((IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies())
.SelectMany<Assembly, System.Type>((Func<Assembly, IEnumerable<System.Type>>)
(assembly =>
{
if (assembly == null)
return (IEnumerable<System.Type>)(new System.Type[0]);
try
{
return (IEnumerable<System.Type>)assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
Debug.LogError(ex);
return (IEnumerable<System.Type>)(new System.Type[0]);
}
})).ToArray<System.Type>();
}
return _types;
}
#endregion
#region Ramp
private static Type EditorWindow_Type = typeof(EditorWindow);
private static MethodInfo EditorWindow_ShowModal_Method = EditorWindow_Type.GetMethod("ShowModal", BindingFlags.NonPublic | BindingFlags.Instance);
// UnityEditor.EditorWindow.ShowModal
// Other windows will not be accessible and any script recompilation will not happen until this window is closed
// https://docs.unity3d.com/ScriptReference/EditorWindow.ShowModal.html
public static void ShowModal(EditorWindow window)
{
#if UNITY_2019_3_OR_NEWER
window.ShowModal();
#else
EditorWindow_ShowModal_Method.Invoke(window, null);
#endif
}
#endregion
#region MaterialProperty.PropertyData
#if UNITY_2022_1_OR_NEWER
private static Type MaterialProperty_Type = typeof(MaterialProperty);
private static Type PropertyData_Type = MaterialProperty_Type.GetNestedType("PropertyData", BindingFlags.NonPublic);
// MergeStack(out bool lockedInChildren, out bool lockedByAncestor, out bool overriden)
private static MethodInfo PropertyData_MergeStack_Method = PropertyData_Type.GetMethod("MergeStack", BindingFlags.Static | BindingFlags.NonPublic);
// HandleApplyRevert(GenericMenu menu, bool singleEditing, UnityEngine.Object[] targets)
private static MethodInfo PropertyData_HandleApplyRevert_Method = PropertyData_Type.GetMethod("HandleApplyRevert", BindingFlags.Static | BindingFlags.NonPublic);
public static void HandleApplyRevert(GenericMenu menu, MaterialProperty prop)
{
System.Object[] parameters = new System.Object[3];
ReflectionHelper.PropertyData_MergeStack_Method.Invoke(null, parameters);
bool lockedInChildren = (bool)parameters[0];
bool lockedByAncestor = (bool)parameters[1];
bool overriden = (bool)parameters[2];
bool singleEditing = prop.targets.Length == 1;
if (overriden)
{
ReflectionHelper.PropertyData_HandleApplyRevert_Method.Invoke(null, new System.Object[]{menu, singleEditing, prop.targets});
menu.AddSeparator("");
}
}
#endif
#endregion
}
}