Files
ichni_Official/Packages/XuanXuanRenderUtility/Editor/GradientRefletctionHelper.cs

249 lines
8.1 KiB
C#
Raw Normal View History

2025-08-27 21:45:18 -04:00
using System;
using System.Reflection;
using UnityEngine;
//因为GradientPicker窗口在窗口打开时使用的是Gradient对象的Cache。
//如果有Undo操作导致MaterialProperty更新了但Gradient却更新不到ColorPicer里。所以在这里进行强制更新。
//后续需要强制更新Picker的时候也可以用这里。
//DeepSeek写的。谨慎用。
public static class GradientReflectionHelper
{
#region GradientPicker
private static Type _gradientPickerType;
// SetCurrentGradient 方法
private static MethodInfo _setGradientMethod;
private static Action<Gradient> _setGradientDelegate;
// RefreshGradientData 方法
private static MethodInfo _refreshMethod;
private static Action _refreshDelegate;
#endregion
#region GradientPreviewCache
private static Type _gradientCacheType;
private static MethodInfo _clearCacheMethod;
private static Action _clearCacheDelegate;
#endregion
// 初始化状态
private static bool _initialized;
private static bool _isValid;
private static readonly object _initLock = new object();
#region API
[System.Diagnostics.Conditional("UNITY_EDITOR")]
public static void SetCurrentGradient(Gradient gradient)
{
ExecuteAction(() =>
{
if (_setGradientDelegate != null)
_setGradientDelegate(gradient);
else if (_setGradientMethod != null)
_setGradientMethod.Invoke(null, new object[] { gradient });
}, "SetCurrentGradient");
}
[System.Diagnostics.Conditional("UNITY_EDITOR")]
public static void RefreshGradientData()
{
ExecuteAction(() =>
{
if (_refreshDelegate != null)
_refreshDelegate();
else if (_refreshMethod != null)
_refreshMethod.Invoke(null, null);
}, "RefreshGradientData");
}
[System.Diagnostics.Conditional("UNITY_EDITOR")]
public static void ClearGradientCache()
{
ExecuteAction(() =>
{
if (_clearCacheDelegate != null)
_clearCacheDelegate();
else if (_clearCacheMethod != null)
_clearCacheMethod.Invoke(null, null);
}, "ClearGradientCache");
}
#endregion
#region
private static void ExecuteAction(Action action, string methodName)
{
if (!Application.isEditor) return;
EnsureInitialized();
if (!_isValid) return;
try
{
action?.Invoke();
}
catch (Exception ex)
{
Debug.LogError($"[GradientReflection] {methodName} failed: {ex.Message}");
// 可选择性地禁用后续调用
// _isValid = false;
}
}
private static void EnsureInitialized()
{
if (_initialized) return;
lock (_initLock)
{
if (_initialized) return;
try
{
// 1. 初始化 GradientPicker 类型
_gradientPickerType = Type.GetType("UnityEditor.GradientPicker, UnityEditor");
if (_gradientPickerType != null)
{
// 初始化 SetCurrentGradient
_setGradientMethod = GetStaticMethod(
_gradientPickerType,
"SetCurrentGradient",
new[] { typeof(Gradient) }
);
if (_setGradientMethod != null)
{
_setGradientDelegate = CreateActionDelegate<Gradient>(_setGradientMethod);
}
// 初始化 RefreshGradientData
_refreshMethod = GetStaticMethod(
_gradientPickerType,
"RefreshGradientData",
Type.EmptyTypes
);
if (_refreshMethod != null)
{
_refreshDelegate = CreateActionDelegate(_refreshMethod);
}
}
else
{
Debug.LogWarning("[GradientReflection] GradientPicker type not found");
}
// 2. 初始化 GradientPreviewCache
_gradientCacheType = Type.GetType("UnityEditorInternal.GradientPreviewCache, UnityEditor");
if (_gradientCacheType != null)
{
_clearCacheMethod = GetStaticMethod(
_gradientCacheType,
"ClearCache",
Type.EmptyTypes
);
if (_clearCacheMethod != null)
{
_clearCacheDelegate = CreateActionDelegate(_clearCacheMethod);
}
}
else
{
Debug.LogWarning("[GradientReflection] GradientPreviewCache type not found");
}
// 3. 验证初始化状态
_isValid = (_setGradientMethod != null || _refreshMethod != null) &&
_clearCacheMethod != null;
if (!_isValid)
{
Debug.LogWarning($"[GradientReflection] Initialization incomplete. " +
$"SetCurrentGradient: {(_setGradientMethod != null ? "OK" : "Missing")}, " +
$"RefreshGradientData: {(_refreshMethod != null ? "OK" : "Missing")}, " +
$"ClearCache: {(_clearCacheMethod != null ? "OK" : "Missing")}");
}
else
{
// Debug.Log("[GradientReflection] Initialized successfully");
}
}
catch (Exception e)
{
Debug.LogError($"[GradientReflection] Initialization failed: {e}");
_isValid = false;
}
finally
{
_initialized = true;
}
}
}
private static MethodInfo GetStaticMethod(Type type, string methodName, Type[] parameterTypes)
{
if (type == null) return null;
return type.GetMethod(
methodName,
BindingFlags.Public | BindingFlags.Static,
null,
parameterTypes,
null
);
}
private static Action CreateActionDelegate(MethodInfo method)
{
try
{
return (Action)Delegate.CreateDelegate(typeof(Action), method);
}
catch (Exception ex)
{
Debug.LogWarning($"[GradientReflection] Failed to create delegate for {method.Name}: {ex.Message}");
return null;
}
}
private static Action<T> CreateActionDelegate<T>(MethodInfo method)
{
try
{
return (Action<T>)Delegate.CreateDelegate(typeof(Action<T>), method);
}
catch (Exception ex)
{
Debug.LogWarning($"[GradientReflection] Failed to create delegate for {method.Name}: {ex.Message}");
return null;
}
}
#endregion
#region
/// <summary>
/// 检查是否所有反射方法都可用
/// </summary>
public static bool IsFullySupported => _isValid;
/// <summary>
/// 获取反射初始化状态
/// </summary>
public static string GetReflectionStatus()
{
if (!_initialized) return "Not Initialized";
return $"GradientPicker: {(_gradientPickerType != null ? "Found" : "Missing")}\n" +
$"- SetCurrentGradient: {(_setGradientMethod != null ? "OK" : "Missing")}\n" +
$"- RefreshGradientData: {(_refreshMethod != null ? "OK" : "Missing")}\n" +
$"GradientPreviewCache: {(_gradientCacheType != null ? "Found" : "Missing")}\n" +
$"- ClearCache: {(_clearCacheMethod != null ? "OK" : "Missing")}";
}
#endregion
}