1
\$\begingroup\$

Unity Editor has the usual bunch of standard tools: translate, rotate, and scale. I want add custom tools (to e.g. "paint" metadata onto the ground, or drag-and-drop stuff between gizmos). How?

\$\endgroup\$
2
  • \$\begingroup\$ Check this out: answers.unity3d.com/questions/41566/… \$\endgroup\$
    – d4Rk
    Apr 12, 2015 at 17:46
  • \$\begingroup\$ Maybe you should provide better detail for what you actually want this tool to do. As it is, "making any tool in unity* is very broad. \$\endgroup\$
    – Gnemlock
    Jul 16, 2017 at 10:11

2 Answers 2

2
\$\begingroup\$

For posterity, this is what I ended up doing:

/// <summary>Derive from this to implement an editor capable of clicking and dragging
/// stuff in the scene view.</summary>
public class SceneViewEditor : Editor
{
    protected static Type currentEditor;
    private bool keepEditing;
    private int mouseDownButton;
    private static Tool previousTool;

    protected bool sceneEditingEnabled
    {
        get { return Tools.current == Tool.None && currentEditor == this.GetType(); }
        set
        {
            var editor = this.GetType();
            if (value ? currentEditor == editor : currentEditor != editor)
                return;
            if (currentEditor == null)
                previousTool = Tools.current;
            Tools.current = value ? Tool.None : previousTool;
            currentEditor = value ? editor : null;
        }
    }

    protected virtual void OnDestroy()
    {
        if (!keepEditing && currentEditor == this.GetType())
        {
            currentEditor = null;
            Tools.current = previousTool;
        }
    }

    // Override this to do your custom scene tool.
    protected virtual void OnSceneClick() { }

    protected virtual void OnSceneGUI()
    {
        // The alt check is there so we don't interfere with orbiting.
        if (!sceneEditingEnabled || Event.current.alt)
            return;
        // The standard hack to take control of all mouse events in the scene view.
        HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));

        var e = Event.current;
        if (!e.isMouse)
            return;

        if (e.type == EventType.MouseUp && e.button == mouseDownButton)
            OnSceneClick();

        mouseDownButton = e.type == EventType.MouseDown ? e.button : -1;
    }

    protected void SetActiveObject(Object value)
    {
        if (value == target)
            return;
        Event.current.Use();
        // If the newly selected object is of the same type as the current, pass the
        // editing baton to the new editor that will be spawned for the newly selected
        // object.
        if (value.GetType() == target.GetType())
            keepEditing = true;
        Selection.activeObject = value;
    }
}

Usage example:

[CustomEditor(typeof(VisibilityArea))]
public sealed class VisibilityAreaEditor : SceneViewEditor
{
    public override void OnInspectorGUI()
    {
        // The usual Editor stuff.
    }

    [DrawGizmo(GizmoType.Active)]
    private static void OnDrawGizmos(VisibilityArea area, GizmoType gizmoType)
    {
        // Get Selection.activeObject, cast it to your type, and draw your custom shit.
        // I never got to implementing this method, so no sample code in here. :(
    }

    protected override void OnSceneClick()
    {
        if (Event.current.button != 0)
            return;
        var gameObject = HandleUtility.PickGameObject(Event.current.mousePosition, false);
        if (gameObject == null)
            return;
        var area = gameObject.GetComponentInParent<VisibilityArea>();
        if (area == null)
            return;
        SetActiveObject(area);
    }
}
\$\endgroup\$
1
\$\begingroup\$

you can extend the editor with your own custom inspectors and Editor Windows. like this: enter image description here

check their official documentation: Extending the Editor

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged .