Hi there, just a quick question. Do there exist some functionality in Unity’s that can tell you whether a class have a designated propertyDrawer?
public bool propertyDrawerBool;
if(propertyDrawerBool)
doStuff();
… that’s not helpful.
He’s asking if there is a way to tell if there is a PropertyDrawer in the project that is associated with a given class. (I don’t know the answer, but I at least know what he’s asking.)
facepalm
I don’t believe there is anything out of the box (more Editor-inclined people would know better) but you could check if a class is annotated with a particular attribute
typeof(MyClass).IsDefined(typeof(MyAttribute), false);
My apologies, I did not realize it was a Class
Yeah, maybe my question isn’t that clear but KelsoMRK and StarManta is on the right track. And Kelso, in regards to your solution, that could surely work, but that would just require some redundant reflection code.
Basically you would have to search your entire assembly, check whether the attribute [CustomPropertyDrawer(typeof(target))] target have been implemented. Then you would have to do an additional check to identify whether target is the same as the class you are comparing with.
I can imagine that references between a class and its target propertydrawer is stored somewhere upon build, and would be good design if these cross-references could be exposed somewhere from developers to use.
Yeah - if you had a lot of customization I could see it being a pain to manage.
What’re you trying to do?
I am currently writing a custom quest editor window script, that makes use of a lot of different custom created ScriptableObject classes. I am interested in drawing the properties of these ScriptableObject classes onto the editor window. My idea is if a certain ScriptableObject class have an assigned custom property drawer, it should make use of that custom property drawer. If no custom property drawer have been assigned the quest editor window will use reflection and access all public attributes from the ScriptableObject class, and draw them by using their default propertyDrawer.
Below is a solution to find out if a type has a property drawer. It uses a bit of reflection as its referencing some of Unity’s internal classes and functions.
But essentially, the unity editor has an internal class called ScriptAttributeUtility, has a dictionary lookup of all of types and their respective property drawers.
public Type GetPropertyDrawer(Type classType)
{
var assembly = Assembly.GetAssembly(typeof(UnityEditor.Editor));
var scriptAttributeUtility = assembly.CreateInstance("UnityEditor.ScriptAttributeUtility");
var scriptAttributeUtilityType = scriptAttributeUtility.GetType();
var bindingFlags = BindingFlags.NonPublic | BindingFlags.Static;
var getDrawerTypeForType = scriptAttributeUtilityType.GetMethod("GetDrawerTypeForType", bindingFlags);
return (Type)getDrawerTypeForType.Invoke(scriptAttributeUtility, new object[] { classType });
}
And this is the equivalent means to get a custom inspector type based on a unity object.
public Type GetCustomEditor(UnityEngine.Object objectRef)
{
var assembly = Assembly.GetAssembly(typeof(UnityEditor.Editor));
var editorAttributes = assembly.CreateInstance("UnityEditor.CustomEditorAttributes");
var type = editorAttributes.GetType();
BindingFlags bf = BindingFlags.Static | BindingFlags.NonPublic;
MethodInfo findCustomEditorType = type.GetMethod("FindCustomEditorType", bf);
return (Type)findCustomEditorType.Invoke(editorAttributes, new object[] { objectRef, false });
}
I found a package SolidAlloy/SolidUtilities: Different utilities that simplify development in Unity3D. (github.com), it contains an extension method HasCustomPropertyDrawer directly calling to the ScriptAttributeUtility methods