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
相关产品推荐
相关产品推荐

