Custom Editor with Handles/Gizmo drawing

I’m currently working on a WYSIWYG tile editor and am running into problems with various methods I have tried.

Ideally I would like to render a camera to a portion of my custom editor window, but haven’t yet been able to figure out how to get that view to also render the Gizmos/Handles of the objects and make them usable. I’ve been over the documentation but haven’t yet found a solution to this.

I have also experimented with a toolbar window, or just having the tools installed in the map’s inspector but this has a number of problems associated with it. These are

  • Event.current misreports it’s values when not used in the OnGUI method of the currently focused window, even with wantsMouseMove set to true in the editor window.
  • The Scene view does not update quickly, and forcing it to do so exacerbates the first problem (Event.current is constantly a repaint event, so things like MouseDrag and MouseUp never get returned)
  • Raycasts never return a hit (even when one should be present) when called from anywhere but OnSceneGUI, which isn’t available to EditorWindows. To get around this I subscribed to the SceneView.onSceneDelegate and used the HandleUtility’s Raycast function which seems to work nicely but necessitates forcing the Scene view to update at a regular interval to correct for lag in the editor.
  • I have been able to get a camera to render to a editor window using Handles.DrawCamera, but I am unable to see Handles or Gizmos in this view

At this point I think the best thing might just be to create a bunch of dummy objects in place of the widgets, and then clean them up when the editor is closed. I’ve also tried extending my editor window from SceneView, but the documentation doesn’t seem to be present and this created some artifacts within the editor window. If anyone has experience with this or knows of a potential solution, it would be greatly appreciated.

I’ve ran into the same issues when working on some plugins… :confused:

Hopefully someone smarter than me comes around.

I’ve made a bit of progress, I managed to get Gizmos to draw in the editor window by making the following call in the Editor Window’s OnGUI method

Handles.DrawCamera(rect, camera, CameraDrawMode.Textured)

Essentially set the third variable to anything but normal and the gizmos will show up. I’m still working on getting the handles to render to the editor window but for the moment I think I can work with this.

EDIT: I’ve worked out the Handle and Gizmo drawing

using the DrawGizmo Attribute I was able to specify gizmo drawing for the target of my tile map editor in my editor window. I can also make a call to Handles drawing functions here, just remember to wrap it in a platform dependent region or else it won’t build properly.

So the steps are

  1. Create editor window, either bring in another camera or create one to be used with in the window
  2. Draw the camera from step one to the custom window with CameraDrawMode set to Textured
  3. Setup DrawGizmo methods in the editor window class to perform custom gizmo drawing. In order to gain access to elements of the editor window class, you’ll most likely need to keep a static reference to it.

This is the post that turned on the light bulb if you need further reference

There is still the problem of the handles not being functional in the editor window.

Here is the basic outline of a custom editor class

public class CustomSceneEditor : EditorWindow
{
    private static CustomSceneEditor _instance = null;
    private Camera _editorCamera = null;

    [MenuItem("Window/Custom Scene Editor")]
    private static void Init()
    {
        _instance = GetWindow<CustomSceneEditor>("Custom Scene Editor");
        // These next two parameters are optional
        _instance.wantsMouseMove = true;
        _instance.autoRepaintOnSceneChange = true;

        GameObject cameraObject = new GameObject("_Custom Editor Camera", typeof(Camera));
        cameraObject.hideFlags = HideFlags.HideAndDontSave;
        _instance._editorCamera = cameraObject.GetComponent<Camera>();
    }

    private void OnDestroy()
    {
        // Destroy the camera when the editor is closed
        Destroy(_editorCamera.gameObject);
    }

    private void OnGUI()
    {
        if (_editorCamera != null)
        {
            // NOTE: This is not a perfect rectangle for the window.  Adjust the size to get the desired result
            Rect cameraRect = new Rect(0f, 0f, position.width, position.height);
            Handles.DrawCamera(cameraRect, _editorCamera, DrawCameraMode.Textured);
        }

        //TODO: perform input handling for editor and camera here
    }

    // Custom Gizmos, Create as many as you'd like
    [DrawGizmo(GizmoType.NotSelected | GizmoType.Selected)]
    //TODO: Replace first argument with the type you are editing
    private static void GizmoTest(Transform aTarget, GizmoType aGizmoType)
    {
        if (_instance == null)
        {
            return;
        }

        // TODO: Perform gizmo drawing here

#if UNITY_EDITOR
        // TODO: Place calls to handle drawing functions in here, otherwise build errors will result
#endif
    }
}
1 Like

In case anyone is interested, I’ve found a solution to all this. Using Handles.BeginGUI() and Handles.EndGUI() you can draw GUI elements to the scene view which makes the whole custom editor window kind of a mute point.

http://docs.unity3d.com/Documentation/ScriptReference/Handles.BeginGUI.html

4 Likes