Search Unity

Official Overlays Developer Guide

Discussion in 'Editor Workflows' started by gabrielw_unity, Dec 8, 2020.

  1. gabrielw_unity

    gabrielw_unity

    Unity Technologies

    Joined:
    Feb 19, 2018
    Posts:
    963
    How to Build Your Own Overlays

    Hello! Here’s a quick-start guide to building your own Overlays with the new system. Please post questions and discussions here, we'll be happy to help out.

    For general Overlays info, and to download the public build, view the Overlays Public Preview thread.

    Please keep in mind, this is an early preview, subject to change.

    The Simplest Way

    1. Create a class that inherits from Overlay class

    class MyOverlay : Overlay
    {
    }


    2. Add the Overlay attribute and provide:
    • Which type of window it can appear in, use EditorWindow type if you want it to appear in any window that supports overlays
    • a unique id
    • A name, this will be displayed in its header and menu
    [Overlay(typeof(SceneView), k_Id, "My Awesome Overlay")]
    class MyOverlay : Overlay
    {
    const string k_Id = "my-custom-overlay";
    }


    3. Implement the CreatePanelContent method and have it return the content you wish to be displayed in the overlay. From this point refer to UI Toolkit docs to know how to build UI.

    public override VisualElement CreatePanelContent()
    {
    var myContent = new VisualElement { name = "my-content" };
    return myContent;
    }


    4. Add the icon attribute to specify which icon to use when collapsed, if no attribute is specified an icon with the 2 most significant letters of the overlay name will be generated for you

    Important Note: IconAttribute is not available in the current preview build, but will be public when released.

    [Overlay(typeof(SceneView), k_Id, "My Awesome Overlay")]
    [Icon("path/to/myIcon.png")]
    class MyOverlay : Overlay
    {
    const string k_Id = "my-custom-overlay";
    }


    Note: If your overlay does not appear, be aware that is the default behavior. Bring up the overlay menu by pressing the space bar in the Scene View (you can change this in the shortcut manager) you should see your overlay appear in the menu.

    Lifecycle

    Overlay visibility can be controlled through Overlay Menu, the 3 dot menu in the corner of the window or through code by directly changing the value of the displayed property. You may want to prevent the users from controlling the visibility and control it yourself ( from a toggle in a toolbar for example ) in this case be sure to set the property userControlledVisibility to false, in the Overlay constructor for example.

    Toolbars

    If implemented this way, you will notice that your overlay will collapse when inserted into a toolbar, you can change this behavior by implementing the ICreateHorizontalToolbar and the ICreateVerticalToolbar interfaces.

    [Overlay(typeof(SceneView), k_Id, "My Awesome Overlay")]
    class MyOverlay : Overlay, ICreateHorizontalToolbar, ICreateVerticalToolbar
    {
    const string k_Id = "my-custom-overlay";
    public override VisualElement CreatePanelContent()
    {
    var myContent = new VisualElement { name = "my-content" };
    return myContent;
    }
    public VisualElement CreateHorizontalToolbarContent()
    {
    var myContent = new VisualElement { name = "my-horizontal-content" };
    return myContent;
    }
    public VisualElement CreateVerticalToolbarContent()
    {
    var myContent = new VisualElement { name = "my-vertical-content" };
    return myContent;
    }
    }


    IMGUI

    If you are converting some existing UI code to use the overlay system, chances are it is written in IMGUI. We strongly advise to take this opportunity to convert your whole UI to UITK. In the case where this is not possible you can use the IMGUIOverlay class.

    [Overlay(typeof(SceneView),k_OverlayID,k_DisplayName)]
    internal class MyIMGUIOverlay : IMGUIOverlay
    {
    public const string k_OverlayID = "my-custom-overlay";
    const string k_DisplayName = "My Awesome Overlay";
    public override void OnGUI()
    {
    //Draw IMGUI stuff here
    }
    }


    Other Windows

    The overlay system is not restricted to the SceneView, any EditorWindow can opt in to have it enabled. All it needs to do is implement the ISupportsOverlays interface. Overlays targeting EditorWindow will automatically be available, otherwise Overlays need to target your EditorWindow type.
     
    Last edited: Dec 8, 2020
  2. Catsoft-Studios

    Catsoft-Studios

    Joined:
    Jan 15, 2011
    Posts:
    703
    That's awesome, waiting for the weekend to try this out. One question, if I may. That [Icon] Attribute, does it necessarily need a string path?

    Will there be a mechanism to inherit from the IconAttribute class and implement your own custom icon? Somthing like this:

    Code (CSharp):
    1. public MyCustomIconAttribute : IconAttribute
    2. {
    3.     public override Texture iconTexture => GenerateMyCustomTexture();
    4.  
    5.     private Texture GenerateMyCustomTexture()
    6.     {
    7.         // custom code that generates a Texture, or loads it from somewhere.
    8.     }
    9. }
    And use it like this

    Code (CSharp):
    1. [Overlay(typeof(SceneView), k_Id, "My Awesome Overlay")]
    2. [MyCustomIcon]
    3. class MyOverlay : Overlay
    4. {
    5.    const string k_Id = "my-custom-overlay";
    6. }
    The reason being that you don't always want to hard-code textures or maybe you want to generate them on the fly (based on whether Unity dark skin is on or off), among other reasons.

    Anyway, I'm super excited about this new Overlays feature!
     
  3. kaarrrllll

    kaarrrllll

    Unity Technologies

    Joined:
    Aug 24, 2017
    Posts:
    552
    The icon loading follows the same path that built-in icons do. It will search for icons matching a naming scheme to best match the current editor theme and screen resolution. Ex, you can provide MyIcon.png d_MyIcon.png MyIcon@2x.png d_MyIcon@2x.png (@2x being resolution, with the "d_" prefix to specific professional theme).
     
    netmarbleneo and Catsoft-Studios like this.
  4. neil_devine

    neil_devine

    Unity Technologies

    Joined:
    Apr 8, 2018
    Posts:
    42
    Hi @Catsoft-Studios, @kaarrrllll beat me to it. At this point yes it does need a string path and unfortunately in this build the IconAttribute is internal, we will make sure to make it public for release. Interested to know what your other use cases would be for generating icons.
     
    Last edited: Dec 9, 2020
    Catsoft-Studios likes this.
  5. Catsoft-Studios

    Catsoft-Studios

    Joined:
    Jan 15, 2011
    Posts:
    703
    Sure! I guess it's a more personal reason, so I understand that's not something that would be widely used. But as an Asset Store developer, I try to have the least amount of textures inside each scripting package. The reason being that I don't want to pollute the user's project with textures he/she shouldn't be using (gizmos, Inspector icons, ...). Otherwise, when they click on any Texture field picker, they get hundreds of textures non-related to their game project.

    For this reason, I'm moving all icons to a hardcoded byte[] array that is reconstructed whenever it's needed using the Texture2D.LoadRawTextureData(...) method. This has the advantage of not getting in the way of the user's texture organisation or naming convention.

    Hope that makes sense, though as I said, as far as I know only Bolt and my (future) packages do it like this. I am more than happy to provide feedback if you have any questions to discuss :)
     
  6. gabrielw_unity

    gabrielw_unity

    Unity Technologies

    Joined:
    Feb 19, 2018
    Posts:
    963
    That's a very cool idea! How is it working out? Similar problems for us/others, of course. If this is a good solution, I can definitely see us wanting to ensure Overlays can work with it.
     
    awesomedata and Catsoft-Studios like this.
  7. Catsoft-Studios

    Catsoft-Studios

    Joined:
    Jan 15, 2011
    Posts:
    703
    Thanks! So far it's working fantastic! I've been using this for a couple of months and there aren't any drawbacks so far. I've attached a screenshot showing how it looks. I wouldn't want to hijack this thread's topic :p So before doing so, let me know if you want me to give the implementation details here or somewhere else.

    Screenshot 2020-12-10 at 18.46.28.png
     
    Last edited: Dec 10, 2020
    wyattt_ and gabrielw_unity like this.
  8. gabrielw_unity

    gabrielw_unity

    Unity Technologies

    Joined:
    Feb 19, 2018
    Posts:
    963
    @Catsoft-Studios - sure, a separate thread would be great, thanks :) I'm hearing from others here that other solutions might be better, maybe they/we can discuss in that thread :)
     
    mariandev and Catsoft-Studios like this.
  9. Catsoft-Studios

    Catsoft-Studios

    Joined:
    Jan 15, 2011
    Posts:
    703
  10. Foriero

    Foriero

    Joined:
    Jan 24, 2012
    Posts:
    584
    @gabrielw_unity Can we use the new tooling system in a production project? We are 2021.1 Thanks, Marek.
     
    Ruchir likes this.
  11. Catsoft-Studios

    Catsoft-Studios

    Joined:
    Jan 15, 2011
    Posts:
    703
    We've been playing witht he Overlay system and it's awesome. It takes some time to get used to it and the contrast between toggles when they are on/off it's a bit too subtle, but overall it's great and a big step forward. More so knowing that can (or will? haven't tried this yet) be used in other EditorWindows.

    One thing we haven't been able to do is to use the BuiltinToolsStrip visual element, along with the ToolButton, to create a chain of buttons that mimics the ones made by Unity.

    @gabrielw_unity - I guess we can create our own stylizing, but I'm wondering whether these will be exposed soon, so we can leverage them in our own tools?
     
    Ziflin likes this.
  12. gabrielw_unity

    gabrielw_unity

    Unity Technologies

    Joined:
    Feb 19, 2018
    Posts:
    963
    2021.2 is where the visuals landed, but the foundation is all there for 2021.1. I'd say upgrade if you can! :D
     
  13. gabrielw_unity

    gabrielw_unity

    Unity Technologies

    Joined:
    Feb 19, 2018
    Posts:
    963
    Hey! :) I would assume that's either on the way, or something else to solve that problem. I'll check!
     
    Catsoft-Studios likes this.
  14. BennyKokMusic

    BennyKokMusic

    Joined:
    Dec 22, 2016
    Posts:
    33
    Quick question, is that the Icon attribute only looks for the path in the "Editor Default Resources" folder?

    How should we go about in a situation that the icon is located in the Packages folder instead of the Assets folder?

    Code (CSharp):
    1. [Overlay(typeof(SceneView), k_OverlayID, k_DisplayName)]
    2. [Icon("proarray-icon.png")]
    3. internal class ProArrayOverlay : IMGUIOverlay
    4. {
    5. ...
    6. }
    upload_2021-5-20_11-46-31.png
     
  15. Catsoft-Studios

    Catsoft-Studios

    Joined:
    Jan 15, 2011
    Posts:
    703
    It looks from the project root. So if you have a texture inside the Assets folder called "MyTexture.png" you use

    Code (CSharp):
    1. [Icon("Assets/MyTexture.png")]
    If your texture is inside the Packages folder, use the "Packages/..." prefix
     
    kaarrrllll and BennyKokMusic like this.
  16. BennyKokMusic

    BennyKokMusic

    Joined:
    Dec 22, 2016
    Posts:
    33
    Thanks! Oh, no wonder, just also figured out the path for individual packages is with the package name instead of the actual folder name. It is working!

    Code (CSharp):
    1. [Overlay(typeof(SceneView), k_OverlayID, k_DisplayName)]
    2. [Icon("Packages/com.bennykok.proarray/Editor/Icons/proarray-icon.png")]
    3. internal class ProArrayOverlay : IMGUIOverlay
    4. {
    5.     ...
    6. }
    Now I'm wondering how to properly handle the icon if the package can be installed both in the Assets folder and Packages folder, after looking at @Catsoft-Studios 's previous reply about extending the IconAttribute, I end up doing something like this, and seems like its working.

    Code (CSharp):
    1. [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
    2. [Conditional("UNITY_EDITOR")]
    3. public class ProArrayIconAttribute : IconAttribute
    4. {
    5.     public ProArrayIconAttribute() : base(GetRelativeIconPath()) {}
    6.     public static string GetRelativeIconPath(string asmdef = "BennyKok.ProArray.Editor")
    7.     {
    8.         var p = Path.GetDirectoryName(CompilationPipeline.GetAssemblyDefinitionFilePathFromAssemblyName(asmdef));
    9.         return p + "/Icons/proarray-icon.png";
    10.     }
    11. }
    12.  
    13. [Overlay(typeof(SceneView), k_OverlayID, k_DisplayName)]
    14. [ProArrayIcon]
    15. internal class ProArrayOverlay : IMGUIOverlay
    16. {
    17. ...
    18. }
     
    oscarAbraham and Catsoft-Studios like this.
  17. owen_proto

    owen_proto

    Joined:
    Mar 18, 2018
    Posts:
    118
    there doesn't seem to be a userControlledVilsibility property as mentioned in the original post. if that property won't be available, another potential solution to my issue would be only allowing my overlay in my custom PreviewSceneStage somehow (implementing ISupportsOverlays and using it as the editor window type in the overlay attribute does not work).

    having purpose-built overlays for custom PreviewSceneStage classes seems like a perfect match. it would be a powerful feature to add if it isn't already possible somehow.
     
    Last edited: Aug 25, 2021
  18. SoxwareInteractive

    SoxwareInteractive

    Joined:
    Jan 31, 2015
    Posts:
    541
    @gabrielw_unity the new overlays seem to break an "old" way of drawing windows in the scene view (using GUILayout.Window) that I've been using in my tools. Is this on purpose?

    To reproduce this, put the following script in an editor folder in Unity 2021.2(b13). Then click on "Window --> Start Test". Notice how no window is shown in the scene view. In the console, "GUILayout.Window() called" is shown and "Callback called" is not shown. Then execute the same script in Unity 2021.1 and notice how the window is drawn correctly.
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4.  
    5. public class Test
    6. {
    7.     [MenuItem("Window/Start Test")]
    8.     public static void MenuItemClicked()
    9.     {
    10.         SceneView.duringSceneGui += OnSceneGUI;
    11.     }
    12.  
    13.     private static void OnSceneGUI(SceneView sceneView)
    14.     {
    15.         Handles.BeginGUI();
    16.  
    17.         Debug.Log("GUILayout.Window() called");
    18.         GUILayout.Window(2, new Rect(sceneView.position.width - 110, sceneView.position.height - 130, 100, 100), WindowCallback, "Title");
    19.  
    20.         Handles.EndGUI();
    21.     }
    22.  
    23.     private static void WindowCallback(int id)
    24.     {
    25.         Debug.Log("Callback called"); // <-- not called in Unity 2021.2b13
    26.         GUILayout.Button("A Button");
    27.     }
    28. }
    29.  
    Is this behavior on purpose or is this a bug?

    Thanks.
     
  19. kaarrrllll

    kaarrrllll

    Unity Technologies

    Joined:
    Aug 24, 2017
    Posts:
    552
    This was a regression, there is a PR in flight to correct it.
     
    SoxwareInteractive likes this.
  20. SoxwareInteractive

    SoxwareInteractive

    Joined:
    Jan 31, 2015
    Posts:
    541
    Ok great, thanks for looking into this. Btw. this is the related bug report ticket (guess you can eventually close this):1369148
     
    kaarrrllll likes this.
  21. RDT42

    RDT42

    Joined:
    Jun 12, 2018
    Posts:
    5
    Hey I've just started trying out Overlays in Unity 2021.2, but I'm having a hard time figuring out how to recreate the default toolbar behavior, where multiple toggles seem to be related, and only one can be pressed at one time. How would I go about recreating that?
     
  22. samanabo

    samanabo

    Joined:
    Mar 10, 2015
    Posts:
    51
  23. SoxwareInteractive

    SoxwareInteractive

    Joined:
    Jan 31, 2015
    Posts:
    541
    Hey @kaarrrllll,
    just wanted to let you know that even though the issue tracker (https://issuetracker.unity3d.com/product/unity/issues/guid/1358677) says that the bug I mentioned earlier is already fixed in Unity 2021.2.x, I can still reproduce it in Unity 2021.2.1f1 with the code example I've provided in my bug report (1369148).

    Another Unity user is also seeing the same behavior (see comment in the issue tracker). May I ask you to please re-visit this bug and check what went wrong? Thank you very much.
     
  24. kaarrrllll

    kaarrrllll

    Unity Technologies

    Joined:
    Aug 24, 2017
    Posts:
    552
    I see that this issue was closed as fixed in 2021.2.1f1, but also that the fix introduced a regression that was subsequently fixed in 2021.2.3f1. Testing on 2021.2.1f1, I confirm that GUI.Window is not working when called from the static SceneView delegate. I tested again on 2021.2.3f1, and verified that it is working as expected.
     
  25. SoxwareInteractive

    SoxwareInteractive

    Joined:
    Jan 31, 2015
    Posts:
    541
    Thank you so much for looking into this and for the explanation what happened behind the scenes. I can confirm that in Unity 2021.2.3f1 everything is functioning as expected again :)
     
    kaarrrllll likes this.
  26. BOXOPHOBIC

    BOXOPHOBIC

    Joined:
    Jul 17, 2015
    Posts:
    508
    Hello,

    Not sure if this is the best place to ask, is there a way to check if any overlays are docked to the "side toolbars"?
    I'm using HandleUtility.WorldToGUIPoint(transform.position) on OnDrawGizmo, but this gives inconsistent results with the overlays. is this a bug or intended?

    Overlay OFF, correct result:
    upload_2021-12-6_15-28-41.png

    Overlays ON, the world to GUI point is missalligned
    upload_2021-12-6_15-29-55.png

    Thank you!

    Edit: It seems that the overlays do not change the screen width or height when overlays are docked, so using those will result in some inconsistencies as well!
     
  27. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Look Blender 3.0 docking system, panels rearrange, header hide, panels minimize... abilities

    They are amazing!
    Wish Unity look into their solution and adopt as much as possible :)
     
  28. Henry00IS

    Henry00IS

    Joined:
    May 20, 2015
    Posts:
    13
    I can confirm this bug. This has been happening with the SabreCSG and RealtimeCSG projects, the toolbars were all under the scene view. I found EditorWindow.position to return the wrong height when there is a docked toolbar overlay on the top of the scene view (it's there by default).

    upload_2021-12-13_21-55-28.png
     
    BOXOPHOBIC likes this.
  29. BOXOPHOBIC

    BOXOPHOBIC

    Joined:
    Jul 17, 2015
    Posts:
    508
    This has the potential to break som many things. I will do a bug report. The window size should scale with overlays accordingly. I'm using HandleUtility.WorldToGUIPoint(transform.position) and this doesn't take the docking into account.

    Edit: For now I came up with this S***ty solution. Docking on the bottom or right side, doesn't change anything, so just checking if docked on top to the left is enough to add some offsets:

    Code (CSharp):
    1.  
    2.         bool switchMode;
    3.         int pixHeightPrev = 0;
    4.         int pixHeightNext = 0;
    5.         int pixWidthPrev = 0;
    6.         int pixWidthNext = 0;
    7.  
    8. ...
    9.  
    10.         switchMode = !switchMode;
    11.  
    12.         if (switchMode)
    13.         {
    14.             pixHeightPrev = SceneView.currentDrawingSceneView.camera.pixelHeight;
    15.             pixWidthPrev = SceneView.currentDrawingSceneView.camera.pixelWidth;
    16.         }
    17.         else
    18.         {
    19.             pixHeightNext = SceneView.currentDrawingSceneView.camera.pixelHeight;
    20.             pixWidthNext = SceneView.currentDrawingSceneView.camera.pixelWidth;
    21.         }
    22.  
    23.         if (pixHeightPrev - pixHeightNext == 26)
    24.         {
    25.             Debug.Log("undocked top bottom");
    26.         }
    27.  
    28.         if (pixHeightNext - pixHeightPrev == 26)
    29.         {
    30.             Debug.Log("docked top bottom");
    31.         }
    32.  
    33.         if (pixWidthPrev - pixWidthNext == 43)
    34.         {
    35.             Debug.Log("undocked side");
    36.         }
    37.  
    38.         if (pixWidthNext - pixWidthPrev == 43)
    39.         {
    40.             Debug.Log("docked side");
    41.         }
     
    Last edited: Dec 14, 2021
  30. MechaWolf99

    MechaWolf99

    Joined:
    Aug 22, 2017
    Posts:
    294
    The reason for this is because it translates a position from world space in the scene to GUI on the editor window, not to the scene rect specifically.
    It is the same for how GUIUtility.GUIToScreenPoint(..) takes a point in the editor window space, and translates it in to a point on the screen. You can also use HandleUtility.WorldToGUIPoint in other windows too iirc. For example if you have a PreviewScene rendering in your own window. Your change would completely break any tool that used this outside of the main SceneView.
     
  31. BOXOPHOBIC

    BOXOPHOBIC

    Joined:
    Jul 17, 2015
    Posts:
    508
    Alright, but how would I use this correctly then. It all worked nicely until the overlays were added.
    var labelPos2D = HandleUtility.WorldToGUIPoint(labelPosition.position);
     
  32. MechaWolf99

    MechaWolf99

    Joined:
    Aug 22, 2017
    Posts:
    294
    Right now it looks like reflection is the only solution. Or to traverse the VisualElement tree of the SceneView window and check for
    #overlay-toolbar__top
    .

    If the devs still watch this thread (which it seems you do). Can you please allow access to info of what overlays are currently open and where they are docked/positioned? This would be really nice to have and allow for more advanced and comprehensive tools/editor extensions.
     
    BOXOPHOBIC likes this.
  33. BOXOPHOBIC

    BOXOPHOBIC

    Joined:
    Jul 17, 2015
    Posts:
    508
    I see, thanks! I'll see what I can do with my limited programming knowledge :(
     
    MechaWolf99 likes this.
  34. SoxwareInteractive

    SoxwareInteractive

    Joined:
    Jan 31, 2015
    Posts:
    541
    Following up on the discussion above, another facet of this issue is that SceneView.position.width / .height is not reduced once an overlay is docked inside the scene view window, but the GUI position origin does get shifted accordingly (so that 0,0 is below the docked overlay).
    I would find it more correct when the scene view's width/height gets updated accordingly to the actual view space i.e. minus the overlay docks. Or maybe add a new property that provides this information if you don't want to break compatibility with existing things.
     
    BOXOPHOBIC likes this.
  35. kaarrrllll

    kaarrrllll

    Unity Technologies

    Joined:
    Aug 24, 2017
    Posts:
    552
    The reason for this is that position is a property on the EditorWindow, not specific to the Scene View. It is by design that it includes the entire content rect.

    It looks like we do have a property that is accounting for the Overlay displacement, but it is internal visibility. I will go ahead and expose it to the public API.
     
  36. John1294

    John1294

    Joined:
    Apr 28, 2016
    Posts:
    7
  37. Querke

    Querke

    Joined:
    Feb 21, 2013
    Posts:
    54
    Hey, is it possible to show an overlay from another script? (I have a toolbar button I'd like to display the overlay when pressed).

    I see that the overlay.displayed property was mentioned, but first the overlay has to be created doesn't it? (And that does mean that the overlay must be created via the triple dots > overlays menu, doesn't it?)
    Any help would be appreciated
     
  38. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    What I do for that is to create a transient overlay. Transient overlays are not controlled by the user, they're instead shown when they return "true" for the visible bool. If you just forward that to a static value you control, you can control it's drawing through that.

    Dummy example:

    Code (csharp):
    1. [Overlay(typeof(SceneView), "Example")]
    2. public class ExampleOverlay : Overlay, ITransientOverlay {
    3.  
    4.     private static bool s_visible;
    5.     public         bool visible => s_visible;
    6.  
    7.     [MenuItem("Example/Overlay")]
    8.     public static void Toggle() {
    9.         s_visible = !s_visible;
    10.     }
    11.  
    12.     public override VisualElement CreatePanelContent() {
    13.         return new Label("Example");
    14.     }
    15. }
     
    kaarrrllll likes this.
  39. Querke

    Querke

    Joined:
    Feb 21, 2013
    Posts:
    54
    Baste to the rescue as always! Thanks, I'll try that.

    Edit: Works perfectly, just what I wanted
     
    Last edited: May 23, 2022
  40. Sir_patrickl

    Sir_patrickl

    Joined:
    Jun 24, 2013
    Posts:
    62
    Hi,

    I've just started to play around with Overlays and really liking it so far. I just have a couple questions:

    1) How do I refresh the contents of an Overlay that is generated from
    CreatePanelContent
    ?

    2) What is the preferred way to create a "context" panel that is displayed under a ToolbarOverlay element? Similar to the one used for Gizmos (in attachment) when clicking on the dropdown. I'm currently using another Overlay to display when a toolbar element is toggled but it feels a bit clunky. The docs show a sample using Handles.BeginGUI() for displaying a color in the scene but I would prefer to use VisualElements and/or Overlays to handle the positioning if that is possible.

    EDIT: You can ignore the first questions since I figured it out. It's super obvious now lol :oops:, I just need to update the bindings of the UIElements. My head was stuck in IMGUI land.
     

    Attached Files:

    Last edited: May 29, 2022
  41. Querke

    Querke

    Joined:
    Feb 21, 2013
    Posts:
    54
    How did you refresh the content of the overlay?
     
  42. Sir_patrickl

    Sir_patrickl

    Joined:
    Jun 24, 2013
    Posts:
    62
    When I create the VisualElement (in
    CreatePanelContent
    ) I just save references to the elements i.e.
    Code (CSharp):
    1. m_StartType =  root.Q<EnumField>("start-type");
    2. m_SpawnDelay = root.Q<FloatField>("spawn-delay");
    I have two methods UnblindElements/RebindElements and I just call these whenever the target object for the Overlay changes.

    For example in
    RebindElements

    Code (CSharp):
    1. m_StartType.value = (EnemyWaveInfo.EnemyWaveStartType) serializedObject.FindProperty("m_StartType").intValue;
    2.         m_StartType.BindProperty(serializedObject.FindProperty("m_StartType"));
     
  43. zander_m

    zander_m

    Joined:
    Feb 7, 2019
    Posts:
    15
    As of 2021.3, userControlledVisibility is internal and cannot be set. The hacky-feeling workaround is to implement the
    ITransientOverlay
    interface and have the visible property always return true. This will create an overlay that cannot be closed by the user.

    For what I was actually trying to accomplish, it would be nice to have a straightforward way to set default overlay visibility and positioning for custom tools.
     
  44. nukadelic

    nukadelic

    Joined:
    Aug 5, 2017
    Posts:
    78
    Needed something similar to the camera overlay behavior which is shown only temporary , so i made this

    upload_2022-8-20_23-57-49.png

    Github [link] - This one will only become visible when the target component type is selected in the scene view

    Code :
    Code (CSharp):
    1. using UnityEngine;
    2. #if UNITY_EDITOR
    3. using UnityEditor;
    4. using UnityEditor.Overlays;
    5. #endif
    6.  
    7. [DisallowMultipleComponent]
    8. public class QuickOverlayExample : MonoBehaviour
    9. {
    10.  
    11.     // normal mono stuff here
    12.  
    13. #if UNITY_EDITOR
    14.     [Overlay(typeof(SceneView) , Title )]
    15.     class QuickOverlay : IMGUIOverlay , ITransientOverlay
    16.     {
    17.         QuickOverlayExample target;
    18.  
    19.         void BurnToScreen() // some dummy ui
    20.         {
    21.             if ( GUILayout.Button("Action") ) { }
    22.  
    23.             GUILayout.Label("YO");
    24.         }
    25.  
    26.         #region Transient Overlay
    27.         const string Title = "Skinned Mesh Vertex";
    28.         public override void OnGUI() { BurnToScreen(); Update(); }
    29.         public override void OnCreated() { Selection.selectionChanged += Update; Update(); }
    30.         public override void OnWillBeDestroyed() { Selection.selectionChanged -= Update; Update(); }
    31.         public bool visible => isVisible;
    32.         bool isVisible = false;
    33.         void Update() {
    34.             if( Selection.activeGameObject == null ) isVisible = ( false );
    35.             else if( Selection.activeGameObject == ( target?.gameObject ?? null ) ) isVisible = ( true );
    36.             else if ( ! Selection.activeGameObject.TryGetComponent( out target ) ) isVisible = ( false );
    37.             else isVisible = ( true );
    38.         }
    39.         #endregion
    40.     }
    41.     #endif
    42. }
    Edit : removed hacks & implemented TransientOverlay
     
    Last edited: Aug 21, 2022
  45. Acegikmo

    Acegikmo

    Joined:
    Jun 23, 2011
    Posts:
    1,294
    Just wanted to check - is there an update on this? currently struggling to draw things from OnDrawGizmos in the scene view without the toolbar offsets, and I can't find a nice way to detect the toolbar height in code
     
    BOXOPHOBIC likes this.
  46. kaarrrllll

    kaarrrllll

    Unity Technologies

    Joined:
    Aug 24, 2017
    Posts:
    552
    adamgolden likes this.
  47. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,555
  48. GamerXP

    GamerXP

    Joined:
    Mar 22, 2014
    Posts:
    78
    Hello! Are those overlays available only in SceneView? I'd like to use them in GameView or main toolbar (one with Enter Player Mode button) as well. Like, for example, put quick-save/quick-load buttons there. Those make no sense to put in SceneView.
     
  49. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    Check the second point in the first post
     
  50. GamerXP

    GamerXP

    Joined:
    Mar 22, 2014
    Posts:
    78
    I saw it, but.. GameView is internal class, so I can't assign it for attribute. And assigning EditorWindow does not seem to add anything anywhere other than in SceneView.