Files
PrinceOfGlory/Assets/Editor/LWGUI-1.x/UnityEditorExtension/ReflectionHelper.cs
kridoo 6e91a0c7f0 111
2025-09-15 17:32:08 +08:00

256 lines
11 KiB
C#

// Copyright (c) Jason Ma
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace LWGUI
{
public static class ReflectionHelper
{
#region MaterialPropertyHandler
private static readonly Type MaterialPropertyHandler_Type = Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.MaterialPropertyHandler");
private static readonly MethodInfo MaterialPropertyHandler_GetHandler_Method = MaterialPropertyHandler_Type.GetMethod("GetHandler", BindingFlags.Static | BindingFlags.NonPublic);
private static readonly PropertyInfo MaterialPropertyHandler_PropertyDrawer_Property = MaterialPropertyHandler_Type.GetProperty("propertyDrawer");
private static readonly 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 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)
{
return GetPropertyDrawer(shader, prop, out _);
}
#endregion
#region MaterialEditor
private static readonly Type MaterialEditor_Type = typeof(MaterialEditor);
private static readonly PropertyInfo MaterialEditor_RendererForAnimationMode_Property = MaterialEditor_Type.GetProperty("rendererForAnimationMode", BindingFlags.NonPublic | BindingFlags.Instance);
public static float DoPowerRangeProperty(Rect position, MaterialProperty prop, GUIContent label, float power)
{
return MaterialEditor.DoPowerRangeProperty(position, prop, label, power);
}
public static void DefaultShaderPropertyInternal(this MaterialEditor editor, Rect position, MaterialProperty prop, GUIContent label)
{
editor.DefaultShaderPropertyInternal(position, prop, label);
}
public static List<Renderer> GetMeshRenderersByMaterialEditor(this MaterialEditor materialEditor)
{
var outRenderers = new List<Renderer>();
// MaterialEditor.ShouldEditorBeHidden()
PropertyEditor property = materialEditor.propertyViewer as PropertyEditor;
if (property)
{
GameObject gameObject = property.tracker.activeEditors[0].target as GameObject;
if (gameObject)
{
outRenderers.AddRange(gameObject.GetComponents<Renderer>());
}
}
return outRenderers;
}
public static Renderer GetRendererForAnimationMode(this MaterialEditor materialEditor)
{
return MaterialEditor_RendererForAnimationMode_Property.GetValue(materialEditor, null) as Renderer;
}
#endregion
#region EditorUtility
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(position, options, enabled, separator, selected, callback, userData, showHotkey);
}
#endregion
#region EditorGUI
public static float EditorGUI_Indent => EditorGUI.indentLevel;
#endregion
#region EditorGUILayout
public static float EditorGUILayout_kLabelFloatMinW => EditorGUILayout.kLabelFloatMinW;
#endregion
#region MaterialEnumDrawer
// UnityEditor.MaterialEnumDrawer(string enumName)
private static Type[] _types;
public static Type[] GetAllTypes()
{
if (_types == null)
{
_types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly =>
{
if (assembly == null)
return Type.EmptyTypes;
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
Debug.LogError(ex);
return Type.EmptyTypes;
}
}).ToArray();
}
return _types;
}
#endregion
#region MaterialProperty.PropertyData
#if UNITY_2022_1_OR_NEWER
private static readonly Type MaterialProperty_Type = typeof(MaterialProperty);
private static readonly Type PropertyData_Type = MaterialProperty_Type.GetNestedType("PropertyData", BindingFlags.NonPublic);
private static readonly MethodInfo PropertyData_MergeStack_Method = PropertyData_Type.GetMethod("MergeStack", BindingFlags.Static | BindingFlags.NonPublic);
private static readonly MethodInfo PropertyData_HandleApplyRevert_Method = PropertyData_Type.GetMethod("HandleApplyRevert", BindingFlags.Static | BindingFlags.NonPublic);
public static void HandleApplyRevert(GenericMenu menu, MaterialProperty prop)
{
var parameters = new object[3];
PropertyData_MergeStack_Method.Invoke(null, parameters);
var overriden = (bool)parameters[2];
var singleEditing = prop.targets.Length == 1;
if (overriden)
{
PropertyData_HandleApplyRevert_Method.Invoke(null, new object[] { menu, singleEditing, prop.targets });
menu.AddSeparator("");
}
}
#endif
#endregion
#region Animation
public static bool MaterialAnimationUtility_OverridePropertyColor(MaterialProperty materialProp, Renderer target, out Color color)
{
return MaterialAnimationUtility.OverridePropertyColor(materialProp, target, out color);
}
#endregion
#region GUI
private static readonly MethodInfo gui_Button_Method = typeof(GUI).GetMethod("Button", BindingFlags.Static | BindingFlags.NonPublic);
public static bool GUI_Button(Rect position, int id, GUIContent content, GUIStyle style)
{
return (bool)gui_Button_Method.Invoke(null, new object[] { position, id, content, style });
}
#endregion
#region GradientEditor
private static readonly FieldInfo k_MaxNumKeys_Field = typeof(GradientEditor).GetField("k_MaxNumKeys", BindingFlags.Static | BindingFlags.NonPublic);
public static readonly int maxGradientKeyCount = (int)k_MaxNumKeys_Field.GetValue(null);
private static readonly FieldInfo m_SelectedSwatch_Field = typeof(GradientEditor).GetField("m_SelectedSwatch", BindingFlags.Instance | BindingFlags.NonPublic);
internal static GradientEditor.Swatch GetSelectedSwatch(this GradientEditor gradientEditor)
{
return m_SelectedSwatch_Field.GetValue(gradientEditor) as GradientEditor.Swatch;
}
internal static void SetSelectedSwatch(this GradientEditor gradientEditor, GradientEditor.Swatch swatch)
{
m_SelectedSwatch_Field.SetValue(gradientEditor, swatch);
}
private static readonly FieldInfo m_RGBSwatches_Field = typeof(GradientEditor).GetField("m_RGBSwatches", BindingFlags.Instance | BindingFlags.NonPublic);
internal static List<GradientEditor.Swatch> GetRGBdSwatches(this GradientEditor gradientEditor)
{
return m_RGBSwatches_Field.GetValue(gradientEditor) as List<GradientEditor.Swatch>;
}
private static readonly FieldInfo m_AlphaSwatches_Field = typeof(GradientEditor).GetField("m_AlphaSwatches", BindingFlags.Instance | BindingFlags.NonPublic);
internal static List<GradientEditor.Swatch> GetAlphaSwatches(this GradientEditor gradientEditor)
{
return m_AlphaSwatches_Field.GetValue(gradientEditor) as List<GradientEditor.Swatch>;
}
private static object s_Styles_Value;
private static readonly FieldInfo s_Styles_Field = typeof(GradientEditor).GetField("s_Styles", BindingFlags.Static | BindingFlags.NonPublic);
public static void GradientEditor_SetStyles()
{
s_Styles_Value ??= Activator.CreateInstance(typeof(GradientEditor).GetNestedType("Styles", BindingFlags.NonPublic));
s_Styles_Field.SetValue(null, s_Styles_Value);
}
private static readonly MethodInfo ShowSwatchArray_Method = typeof(GradientEditor)
.GetMethod("ShowSwatchArray", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Rect), typeof(List<GradientEditor.Swatch>), typeof(bool) }, null);
internal static void ShowSwatchArray(this GradientEditor gradientEditor, Rect position, List<GradientEditor.Swatch> swatches, bool isAlpha)
{
ShowSwatchArray_Method.Invoke(gradientEditor, new object[] { position, swatches, isAlpha });
}
private static readonly MethodInfo GetTime_Method = typeof(GradientEditor).GetMethod("GetTime", BindingFlags.Instance | BindingFlags.NonPublic);
internal static float GetTime(this GradientEditor gradientEditor, float actualTime)
{
return (float)GetTime_Method.Invoke(gradientEditor, new object[] { actualTime });
}
#endregion
#region CurveEditor
private static readonly FieldInfo m_CurveEditor_Field = typeof(CurveEditorWindow).GetField("m_CurveEditor", BindingFlags.Instance | BindingFlags.NonPublic);
internal static CurveEditor GetCurveEditor(this CurveEditorWindow curveEditorWindow)
{
return m_CurveEditor_Field.GetValue(curveEditorWindow) as CurveEditor;
}
private static readonly MethodInfo AddKeyAtTime_Method = typeof(CurveEditor).GetMethod("AddKeyAtTime", BindingFlags.Instance | BindingFlags.NonPublic);
internal static CurveSelection AddKeyAtTime(this CurveEditor curveEditor, CurveWrapper cw, float time)
{
return AddKeyAtTime_Method.Invoke(curveEditor, new object[] { cw, time }) as CurveSelection;
}
#endregion
}
}