You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何根据关联类型获取CustomPropertyDrawer标记的PropertyDrawer子类?

Unity中通过自定义类型获取关联的PropertyDrawer类型

当然可以实现这个需求,核心思路是通过反射遍历所有加载的程序集,查找带有CustomPropertyDrawer特性且目标类型匹配的PropertyDrawer派生类。以下是通用的实现方案:

通用工具方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;

public static class DrawerUtility
{
    // 缓存已找到的Drawer映射,避免重复遍历提升性能
    private static readonly Dictionary<Type, Type> _drawerCache = new Dictionary<Type, Type>();

    public static Type GetPropertyDrawerType(Type targetType)
    {
        if (_drawerCache.TryGetValue(targetType, out var cachedType))
            return cachedType;

        // 遍历当前AppDomain下的所有程序集
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            try
            {
                // 筛选出所有非抽象的PropertyDrawer派生类
                var drawerCandidates = assembly.GetTypes()
                    .Where(t => typeof(PropertyDrawer).IsAssignableFrom(t) && !t.IsAbstract);

                foreach (var drawerType in drawerCandidates)
                {
                    // 获取类上的CustomPropertyDrawer特性
                    var drawerAttr = drawerType.GetCustomAttribute<CustomPropertyDrawer>();
                    if (drawerAttr == null) continue;

                    // 匹配目标类型,同时支持特性的useForChildren参数(子类也能匹配)
                    bool isMatch = drawerAttr.targetType == targetType || 
                                   (drawerAttr.useForChildren && targetType.IsSubclassOf(drawerAttr.targetType));

                    if (isMatch)
                    {
                        _drawerCache[targetType] = drawerType;
                        return drawerType;
                    }
                }
            }
            catch (ReflectionTypeLoadException)
            {
                // 跳过加载失败的程序集(比如某些Unity内置程序集可能无法完整加载)
                continue;
            }
        }

        // 未找到对应Drawer时返回null
        _drawerCache[targetType] = null;
        return null;
    }
}

使用示例

// 获取MyCustomType对应的Drawer类型
Type myDrawerType = DrawerUtility.GetPropertyDrawerType(typeof(MyCustomType));

if (myDrawerType != null)
{
    // 实例化Drawer(如果需要)
    PropertyDrawer drawerInstance = (PropertyDrawer)Activator.CreateInstance(myDrawerType);
    // 后续可调用Drawer的方法或做其他处理
}

补充说明

  • 工具类中加入了缓存机制,避免每次调用都遍历所有程序集,提升重复调用的性能
  • 支持CustomPropertyDrawer特性的useForChildren参数,即如果某个Drawer标记了useForChildren = true,它的子类类型也能匹配到该Drawer
  • 遍历过程中会跳过加载失败的程序集,避免抛出异常

内容的提问来源于stack exchange,提问作者Bri Bri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 08:18:36