Search Unity

How to get the Class or Instance of a Custom Editor of a specific Component?

Discussion in 'Scripting' started by Usmith, Nov 28, 2013.

  1. Usmith

    Usmith

    Joined:
    Apr 7, 2013
    Posts:
    20
    Hi all, I'm working around to customize a context menu if you right-click on a game object in the hierarchy window, by using **EditorApplication.hierarchyWindowItemOnGUI**, i make a lot of progress, but the problem is , i don't want to mix all of those drawing-context code together but to scatter them to each component's own editor class(or editor instance), and so far i didn't find a way to get the class (or instance), anybody knows how?
     
  2. Usmith

    Usmith

    Joined:
    Apr 7, 2013
    Posts:
    20
    nobody knows?
     
  3. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
  4. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    If you have a reference to the Monobehaviour/GameObject instance which has an editor class defined for it, it is possible to create the editor via code using Editor.CreateEditor
     
  5. Usmith

    Usmith

    Joined:
    Apr 7, 2013
    Posts:
    20
    yeah i think this might be the thing i want, i shoul leave the second parameter empty and it should return a default editor instance to me, i'll try it , thanks a lot~
     
  6. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    If I want to access a component from another editor script, I'll have this:
    Code (csharp):
    1.  
    2. public class SomeComponent : MonoBehaviour {
    3. #if UNITY_EDITOR
    4.    public void SomeScriptToAccessFromEditors() {
    5.      if (!Application.isPlaying) {
    6.        // Editor Code I want to access from ANY editor, not just this component's editor.
    7.      }
    8.    }
    9. #endif
    10. }
    Then I can call this script from this component's editor, while also being able to call it from other editors.

    Another helpful thing I see is a Helper or Utility class with static functions that can be passed a component to do work on from any editor. This doesn't sound like what you want though as you want to have custom functionality for each script instead of consolidating functionality in a single class.
     
  7. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    393
    If you know your editor(s) definitely exists because it's currently opened (perhaps on the same gameObject), then you can use this approach:

    Code (CSharp):
    1. class MyEditor : Editor{
    2.  
    3. //NOTICE - check that the sampeld editor isn't null, whenever sampling
    4.     public static HashSet<MyEditor> _editors = new HashSet<MyEditor>();
    5.  
    6.  
    7.     void OnEnable(){
    8.          _editors.Add(this);
    9.     }
    10.  
    11.    void OnDisable(){
    12.           _editors.Remove(this);
    13.    }
    14. }
    Anybody else can then use MyEditor._editors, which works instead of Object.FindObjectsOfType<MyEditor>(). The latter doesn't seem to work for editors, but the static Hashset does.
     
    Pleija likes this.
  8. Dr-Nick

    Dr-Nick

    Joined:
    Sep 9, 2013
    Posts:
    25
    May not be entirely related but if are wanting to know if a unity object (eg Monobehaviour / ScriptableObject) has a CustomEditor written for it, you can use this method.

    Code (CSharp):
    1.     public Type GetCustomEditor(UnityEngine.Object objectRef)
    2.     {
    3.         var assembly = Assembly.GetAssembly(typeof(UnityEditor.Editor));
    4.         var editorAttributes = assembly.CreateInstance("UnityEditor.CustomEditorAttributes");
    5.  
    6.         var type = editorAttributes.GetType();
    7.         BindingFlags bf = BindingFlags.Static | BindingFlags.NonPublic;
    8.  
    9.         MethodInfo findCustomEditorType = type.GetMethod("FindCustomEditorType", bf);
    10.         return (Type)findCustomEditorType.Invoke(editorAttributes, new object[] { objectRef, false });
    11.  
    12.     }