Search Unity

Question How to inject context menu into an existing Editor Window ?

Discussion in 'Editor Workflows' started by apeyromaure, Feb 22, 2024.

  1. apeyromaure

    apeyromaure

    Joined:
    Nov 15, 2023
    Posts:
    3
    Hi all, I'm wondering if it's possible to inject new context menu into an existing EditorWindow's contextual menu.

    Here's an exemple to illustrate what I mean:
    When I right-click on a parameter in my Animator window, I want to be able to have a new menu item in the context menu that will let me execute custom code.

    I want to emphasize that I want to do this on existing editors I can't edit.
    I tried to work with MenuItem but from what I understand it only works for the main menu (i.e. top menu bar) and the inspector.
     
  2. lleondlg05

    lleondlg05

    Joined:
    Aug 28, 2018
    Posts:
    7
    Hi, friend!

    I'm not sure I fully understand what you want.

    Correct me if I'm wrong but you want to right click on a property of an object and display a custom context menu.
    You can do this by creating a GenericMenu and calling ShowAsContext on it.

    Check if the mouse event is on click down 1, and if the mouse position is inside the rect property and then use GenericMenu

    If not, propertyDrawers may be what you need :)
     
  3. apeyromaure

    apeyromaure

    Joined:
    Nov 15, 2023
    Posts:
    3
    Here's a screenshot to illustrate what I want.

    The tricky part here is that I'm working in an editor window for which I don't have the code.
     

    Attached Files:

  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    It looks doable, but it'll be dirty, and there are problems. All the information below has been found by Rider automatically decompiling the relevant files.

    The Animator is IMGUI-based rather than UITK-based, so there's no nice way to just query for the correct object. The list of parameters is a ReorderableList, though, which means that the right-click menu is a callback that you can swap out.

    So you need to grab the Animator window, which is a
    UnityEditor.Graphs.AnimatorControllerTool
    . You can find it through Resources.FindObjectsOfTypeAll<EditorWindow>, but that'll be very slow to do a bunch, but more on that later.

    From there, you want to grab the
    private ParameterControllerView m_ParameterEditor
    , and then find it's
    protected ReorderableList m_ParameterList
    , and then reassign it's
    drawElementCallback
    . This is a bit silly, you'd hope that it'd be possible to just reassign the
    onMouseUpCallback
    , but the right-click menu is implemented by checking if the current event is a MouseUp for the right mouse button, and if the drawn rect contains the mouse - probably because onMouseUpCallback is global to the list.

    So what you actually need to do is to not only replace what happens with the right-click menu, but also replace the entire drawElementCallback. That's also doable, if you can decompile the code and see what's already there, and basically copy-paste it and change what the GenericMenu does.

    Oh and by the way, almost everything I've written here requires Reflection, as most of these types are internal. The only thing that isn't is the ReorderableList itself.

    Finally, there's the problem of injecting into the correct window. There's no event in the editor that I know of that fires when you open a window. So either you have to have a manual button to activate your injection, which is a drag, or you have to just run code that looks through all editor windows regularly, which sounds very slow. AnimatorControllerTool isn't sealed, so in theory it's possible to subclass it, but it's internal and in a dll in
    Editor\Data\Managed\UnityEditor.Graphs.dll
    , so I don't know of any practical way to inject anything into it's assembly.


    So, in short, replacing the menu is very doable, but it requires a hack to inject stuff into there. Having your injection run when you need it, without user intervention, is not something I know how you can achieve, so you might have to add a custom menu item behind a shortcut or whatever to do it.
     
  5. apeyromaure

    apeyromaure

    Joined:
    Nov 15, 2023
    Posts:
    3
    That's what I feared, it doesn't seam to be a supported feature but is still doable with reflection.

    I'll dig the reflection approach when I have some spare time. Thanks for your investigations it will help a lot. :)