Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Inject GUI code in InspectorWindow

Discussion in 'Immediate Mode GUI (IMGUI)' started by Aceria_, Mar 24, 2015.

  1. Aceria_

    Aceria_

    Joined:
    Oct 20, 2014
    Posts:
    81
    I was working on some tools that would make my life easier, and I was wondering if it was possible to inject GUI code on the red line here (see image blow, it's in the Inspector Window). So above the first component and below the "tag" & "layer" dropdown.

    redline.png

    I could always write a custom editor that overrides the Transform (and simply draws the buttons at the very top), but that would be really annoying if I had multiple scripts that I would like to add there.
     
  2. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    I never tried this, but from what I know, the process is handled like this (these are all internal Unity classes):
    • InspectorWindow holds references to all the custom editors (Editor-derived classes) in it.
    • The top part (the one you highlighted) is handled by the GameObjectInspector class:
    Code (CSharp):
    1. [CanEditMultipleObjects, CustomEditor (typeof(GameObject))]
    2. internal class GameObjectInspector : Editor
    3. {
    4. }
    Specifically, this editor overrides the OnHeaderGUI and shows what you see there (the OnInspectorGUI method for this editor is empty).

    You can create an editor of your own for the GameObject type, implement whatever logic you want in its OnInspectorGUI method, and call the default implementation in its OnHeaderGUI.

    So, overall, it would look something like this:
    Code (CSharp):
    1. [CustomEditor(typeof(GameObject))]
    2. public class TestInspector : Editor
    3. {
    4.     private Type inspectorType;
    5.     private Editor editorInstance;
    6.     private MethodInfo defaultHeaderGUI;
    7.  
    8.     public TestInspector ()
    9.     {
    10.         inspectorType = System.Reflection.Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.GameObjectInspector");
    11.         defaultHeaderGUI = inspectorType.GetMethod("OnHeaderGUI",
    12.                                                    System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
    13.     }
    14.  
    15.     protected override void OnHeaderGUI ()
    16.     {
    17.         editorInstance = Editor.CreateEditor(target, inspectorType);
    18.    
    19.         defaultHeaderGUI.Invoke(editorInstance, null);
    20.         // Add more custom code here or in OnGUI()
    21.     }
    22. }
     
    Last edited: Mar 25, 2015
    Hosnkobf and CanisLupus like this.
  3. Aceria

    Aceria

    Joined:
    Jun 14, 2012
    Posts:
    3
    GameObjectInspector was what I was looking for, thanks!
    Your code is pretty much spot on (apart from a few typos), the only real addition is that you have to add an empty OnInspectorGUI() method, else it'll print all the variables again in a list. The final code ends up like this:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Runtime.InteropServices;
    5.  
    6. [CustomEditor(typeof(GameObject))]
    7. public class GameObjectInspectorOverride : Editor{
    8.     private System.Type inspectorType;
    9.     private Editor editorInstance;
    10.     private _MethodInfo defaultHeaderGUI;
    11.  
    12.     public GameObjectInspectorOverride(){
    13.         inspectorType = System.Reflection.Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.GameObjectInspector");
    14.         defaultHeaderGUI = inspectorType.GetMethod("OnHeaderGUI", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
    15.     }
    16.  
    17.     protected override void OnHeaderGUI(){
    18.         editorInstance = Editor.CreateEditor(target, inspectorType);
    19.         defaultHeaderGUI.Invoke(editorInstance, null);
    20.      
    21.         //custom GUI code here
    22.     }
    23.  
    24.     public override void OnInspectorGUI(){ }
    25. }
    26.  
    Thanks for the help!
     
    CanisLupus and liortal like this.
  4. BMayne

    BMayne

    Joined:
    Aug 4, 2014
    Posts:
    186
    Hey there,

    I think you can skip the reflection and just use
    Code (CSharp):
    1.     DrawHeader();
    It's a function in the Editor class.
     
  5. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    If you mean drop invoking OnHeaderGUI via reflection then yes you're right.
    You still have to grab the original editor type via reflection though.

    I have a blog post + usable code for this scenario coming up real soon. Check out my site http://www.tallior.com