Search Unity

Feedback Get editor type for target type without using instances

Discussion in 'Scripting' started by Xarbrough, Oct 6, 2019.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    Unity automatically creates a custom editor for target instances, e.g. I have a MonoBehaviour component and Unity either picks the builtin editor or uses my custom editor, etc. I can also manually create a matching editor by using
    Editor editorInstance = Editor.CreateEditor(target)
    , which returns an instance of the editor that Unity wants to use.

    How can I retrieve the type of editor that Unity will return for a specific target type without first creating an instance? In my use case I don't need the actual instance, I only want to know the class type or script being used for additional functionality like opening a script file at path or simply showing which editor is currently configured.

    I believe there is no public API for this yet, so this is my feedback request. I would imagine a simply API like this:
    System.Type editorType = Editor.GetEditorType(typeof(MyMonoBehaviour))
     
  2. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    Internally in Unity, there's a type->editor type dictionary, and some utilities for doing exactly what you're asking. I have reflected in there to replace editors before, but I don't quite remember the details.

    So this is a matter of making an internal API public, but I'm pretty curious about what you need it for.
     
  3. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    I have added context menu entries for custom assets and components with small utility functions such as "Select Asset" or "Select Script" or "Edit Editor Script". The last one should open the custom editor script for a component analog to the "Edit Script" context menu. To do this, I create a throwaway editor via Editor.CreateEditor and then create a MonoScript from it to automatically find the asset path in the project folder which I can use to open the configured script editor. Something like this:

    Code (CSharp):
    1.  
    2. [MenuItem("CONTEXT/ScriptableObject/Edit Editor Script", priority = 0)]
    3. [MenuItem("CONTEXT/MonoBehaviour/Edit Editor Script", priority = 610)]
    4. public static void EditEditorScript(MenuCommand command)
    5. {
    6.     Editor editor = Editor.CreateEditor(command.context);
    7.  
    8.     if (editor == null)
    9.         return;
    10.  
    11.     if (editor.GetType().Namespace.Contains("UnityEditor"))
    12.     {
    13.         Object.DestroyImmediate(editor);
    14.         return;
    15.     }
    16.  
    17.     var script = MonoScript.FromScriptableObject(editor);
    18.     string path = AssetDatabase.GetAssetPath(script);
    19.     if (path == string.Empty)
    20.         return;
    21.  
    22.     AssetDatabase.OpenAsset(script);
    23.     Object.DestroyImmediate(editor);
    24. }
    This works fine (as start, still needs correct priority and maybe more error handling) but it feels pretty ugly to create all these object instances just to open a script. And more importantly, this utility is of course only helpful if users have defined a custom editor. Ideally, I would check via the validation function if such a type is available and if not, gray the context menu out. In the current implemention it simply fails to open anything. But I really don't want to create multiple editor instances everytime a context menu is created on any object, instead checking only for a type should be possible without allocating garbage.
     
    Last edited: Oct 6, 2019