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

Draw native OnSceneGUI options for custom EditorWindow

Discussion in 'Immediate Mode GUI (IMGUI)' started by ReneBaumgartner, Jul 23, 2014.

  1. ReneBaumgartner

    ReneBaumgartner

    Joined:
    May 3, 2014
    Posts:
    13
    Hello there!

    I want to create a native options menu inside the SceneView (have a look at the attached image) from my custom EditorWindow.

    OnSceneOptions.png

    I already know that i can draw GUI controls inside the SceneView with this code:

    Code (CSharp):
    1. #if UNITY_EDITOR
    2.  
    3. using UnityEngine;
    4. using UnityEditor;
    5.  
    6. public class MyCustomEditorWindow : EditorWindow
    7. {      
    8.     void OnEnable()
    9.     {
    10.         SceneView.onSceneGUIDelegate += this.OnSceneGUI;
    11.     }
    12.  
    13.     void OnDisable()
    14.     {
    15.         SceneView.onSceneGUIDelegate -= this.OnSceneGUI;
    16.     }
    17.  
    18.     void OnSceneGUI( SceneView sceneView )
    19.     {
    20.         if( SceneView.lastActiveSceneView != null )
    21.         {
    22.             Handles.BeginGUI();
    23.  
    24.             // Draw something here using GUI or GUILayout...
    25.      
    26.             Handles.EndGUI();
    27.             SceneView.lastActiveSceneView.Repaint();
    28.         }
    29.     }
    30. }
    31. #endif
    Now I want to achieve the same behaviour as the native OnScene options - like those from the "Navigation" or "Occlusion Culling" EditorWindows or from an inspected camera (the little preview in the bottom right).

    When you open/close those tabs, the options arrange themselves properly so nothing gets occluded.

    In addition it would be nice to also style them properly - maybe using the undocumented styles from the default editor skin.. But that's the second step ;)

    Any thoughts on this? Thank you in advance!

    Best,
    Rene
     
    sandolkakos likes this.
  2. Dabartos

    Dabartos

    Joined:
    May 26, 2016
    Posts:
    33
    necrobump?
     
  3. sandolkakos

    sandolkakos

    Joined:
    Jun 3, 2009
    Posts:
    282
  4. FrischGebraut

    FrischGebraut

    Joined:
    Jul 24, 2013
    Posts:
    28
    Reviving this post for future reference. Unity uses the internal class UnityEditor.OverlayWindow for these kind of scene windows. You can create your own using reflection:
    Code (CSharp):
    1.  
    2. // Add these instance fields to your Editor/EditorWindow
    3. private object sceneOverlayWindow;
    4. private MethodInfo showSceneViewOverlay;
    5.  
    6. void OnEnable()
    7. {
    8. var unityEditor = Assembly.GetAssembly(typeof(UnityEditor.SceneView));
    9. var overlayWindowType = unityEditor.GetType("UnityEditor.OverlayWindow");
    10. var sceneViewOverlayType = unityEditor.GetType("UnityEditor.SceneViewOverlay");
    11. var windowFuncType = sceneViewOverlayType.GetNestedType("WindowFunction");
    12. var windowFunc = Delegate.CreateDelegate(windowFuncType, this.GetType().GetMethod(nameof(DoOverlayUI), BindingFlags.Static | BindingFlags.NonPublic));
    13. var windowDisplayOptionType = sceneViewOverlayType.GetNestedType("WindowDisplayOption");
    14. sceneOverlayWindow = Activator.CreateInstance(overlayWindowType,
    15.                 EditorGUIUtility.TrTextContent("Window Title", (string)null, (Texture)null), // Title
    16.                 windowFunc, // Draw function of the window
    17.                 int.MaxValue, // Priority of the window
    18.                 (UnityEngine.Object) Target, // Unity Obect that will be passed to the drawing function
    19.                 Enum.Parse(windowDisplayOptionType, "OneWindowPerTarget") //SceneViewOverlay.WindowDisplayOption.OneWindowPerTarget
    20.             );
    21.             showSceneViewOverlay = sceneViewOverlayType.GetMethod("ShowWindow", BindingFlags.Static | BindingFlags.Public);
    22. }
    the above code is for initialization (for example inside of OnEnable of an Editor or EditorWindow). Then simply draw the window in OnSceneGUI:
    Code (CSharp):
    1. private void OnSceneGUI()
    2. {
    3.    showSceneViewOverlay.Invoke(null, new object[] {sceneOverlayWindow});
    4. }
    the window content is drawn in the callback function you pass into the SceneViewOverlay:

    Code (CSharp):
    1. private static void DoOverlayUI(UnityEngine.Object target, SceneView sceneView)
    2. {
    3.     GUILayout.Button("Hello there");
    4. }
    hope that helps anyone.
     
    yangjifeiOutlook likes this.
  5. Camarent

    Camarent

    Joined:
    Feb 19, 2014
    Posts:
    168
    Right now there is more convenient way to do it. You need to use SceneVisibilityManager.
    It is easy way to disable picking and view in editor only.
     
  6. FrischGebraut

    FrischGebraut

    Joined:
    Jul 24, 2013
    Posts:
    28
    Looking at the reference of SceneVisibilityManager I can't seem to find anything related to the scene overlay window. Could you specify what part of the API you are talking about?
     
  7. Camarent

    Camarent

    Joined:
    Feb 19, 2014
    Posts:
    168
    Oh sorry I misclicked a thread!
     
  8. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,296
    Arise
    Did someone manage to find the way? or this is internal API only (shame if it is)?
     
  9. FrischGebraut

    FrischGebraut

    Joined:
    Jul 24, 2013
    Posts:
    28
    As far as I know it is still an internal API only. However, you can use reflection to access the window (check my answer). Also take a look at the implementation currently used by the Chisel devs. It also uses reflection but is cleaner and handles different Unity versions.
     
  10. fuser

    fuser

    Joined:
    Nov 23, 2013
    Posts:
    10
    I found this thread while trying to do this myself. I found that Unity 2021.2 now supports Overlays without the need for reflection, you can see how to interact with them from a designer's perspective here, and I couldn't find an authoring tutorial so I wrote my own one here.
     
    budukratok and ikkou0v0 like this.