Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Docking Editor Windows Side By Side Via Script

Discussion in 'Scripting' started by DanielleOlson, Jul 19, 2013.

  1. DanielleOlson


    Jul 19, 2013
    I've been pursuing the ability to fully customize editor tools for a while now, including being able to set up panels in a consistent way for all of the artists who use the tool. Currently the best I can do is have our multi-panel tools pop up with all the tabs stacked in a single window. It's not hard to just drag the tab to dock on the right side, but many artists and designers miss that the tab is even there, and then miss important functionality of the tool. On opening the tool, that solution looks like this:


    Desired Outcome
    Since my goal is to help all of our content creators (I'm working on a large team of about 60) have a consistent interface with our custom data, the ability to format these panels is very important to me. My goal is for the tool to pop up with the panels already laid out, something like this:


    I've looked around a lot for other resources on this idea. The problem is very often confused for just opening a tab in the same window (like my first image):
    Or being done by hand:
    Some suggest saving an entire layout, which isn't an acceptable solution for me (artists and designers will often have their own custom layouts, and forcing them to alter this would make them less likely to use the tool as designed)

    It's Possible!
    This video shows exactly what I'm trying to accomplish:
    And the guy's forum name is Tertle!
    From the above thread, it seems very likely that reflection was used to achieve docking through script. Hey Tertle, if you happen upon this thread could you lend some insight as to how you got your docking to work, and if you ever overcame the problem your method was having on Macs?

    Based on the evidence of my own trial and error and the findings above, I've come to the unfortunate conclusion that reflection is the only way to achieve custom window docking :( This means our tools will be subject to instability at new Unity releases, and just the development of the functionality itself will be a pain. My current plan of attack is to set up an overlay system for accessing the following internal classes:


    And trying to use the SplitView.PerformDrop method to get my EditorWindows where I want them to be. Again, not terribly happy about this, would love to do it some other way.

    If anyone has tried this, successfully or unsuccessfully, it would be great to hear about your experiences. And if anyone from Unity has some input on the likelihood of this becoming a supported feature, that would be awesome too! I will provide updates on my progress, if I make any.

  2. spolglase


    Jan 13, 2011
    Did you ever figure this out. I'm running into the same problem. Did you ever figure out a solution using reflection?
  3. spolglase


    Jan 13, 2011
    I've made some headway on this problem. However now I'm getting an exception on the PerformDrop call. Here's the message I sent to Tertle:

  4. spolglase


    Jan 13, 2011
    I finally got it working. There were two important steps I was missing.

    The first was converting my Event.current.mousePosition Vector2 to a screen point using GUIUtility.GUIToScreenPoint().

    The second step I was missing was setting the s_OriginalDragSource static member of DockArea to be my child EditorWindow's DockArea. This is necessary because within the PerformDrop() call it needs to remove the child EditorWindow from the old DockArea and it will throw a null ref if it isn't properly set.

    You can see the new non-reflection code below:

    Code (csharp):
    1. public static void DockEditorWindow(Vector2 mousePos, EditorWindow parent, EditorWindow child)
    2. {
    3.      Vector2 screenPoint = GUIUtility.GUIToScreenPoint(mousePos);
    4.      DockArea area = parent.m_Parent as DockArea;
    5.      SplitView sv = area.m_parent as SplitView;
    6.      DropInfo di = sv.DragOver(child, screenPoint);
    7.      DockArea.s_OriginalDragSource = child.m_Parent;
    8.      sv.PerformDrop(child, di, screenPoint);
    9. }

    Also on a separate note this code works as of Unity 4.1.3. It's always possible that they change the internals of how this stuff works in later versions of Unity.
    Last edited: Dec 3, 2013
    Eldoir and Novack like this.
  5. Thundernerd


    Jan 24, 2014
    Thanks so much for this. I was looking for a way to make this work but I couldn't figure out how. This was the only thread that had some sensible information. Had to do some reflection but I finally got it to work!

    And this is how I fixed it:
    Last edited: Mar 16, 2017