[编辑器]Unity的SceneView自定义鼠标事件

时间:2022-05-28 03:28:19

1 监听OnSceneGUI:

[InitializeOnLoadMethod]
static void Init()
{
    SceneView.onSceneGUIDelegate += OnSceneGUI;
}

static void OnSceneGUI(SceneView sceneView)
{
......
}

 

2 修改将资源从Project视图拖进Scene视图的事件:

比如拖texture或sprite进去,默认创建SpriteRenderer,此时想改成创建Image,需要在上面的OnSceneGUI中监听拖拽事件EventType.DragUpdated和EventType.DragPerform,拖拽时,DragDrop.objectReferences是拖拽的文件(可以有多个):

if (Event.current.type == EventType.DragUpdated || Event.current.type == EventType.DragPerform)
{
    if (!IsImageAsset (DragAndDrop.objectReferences [0]))
    {
        //如果不能创建Image返回让系统自己处理。
        return;
    }
    DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

    if (Event.current.type == EventType.DragPerform)
        //松开鼠标
    {
        DragAndDrop.AcceptDrag();
        //此处添加创建Image的代码
        ......
    }
    Event.current.Use ();
}

 

松开鼠标后,将鼠标屏幕坐标转换为SceneView坐标:

static Vector3 GetWorldPosition (SceneView sceneView, Transform parent)
{
    Camera cam = sceneView.camera;
    Vector3 mousepos = Event.current.mousePosition;
    mousepos.z = -cam.worldToCameraMatrix.MultiplyPoint (parent.position).z;
    mousepos.y = cam.pixelHeight - mousepos.y;
    mousepos = sceneView.camera.ScreenToWorldPoint (mousepos);
    return mousepos;
}

其中parent是Image要挂载的父节点的transform:

var parent = Selection.activeGameObject;
if (child != null && parent != null)
{
    Vector3 worldPos = GetWorldPosition (sceneView, parent);
    child.SetParent (parent, false);
    child.transform.position = worldPos;
    Selection.activeGameObject = child.gameObject;
}

 

3 SceneView中添加右键菜单:

同样需要在OnSceneGUI中监听事件:

if (Event.current.button == 1 && Event.current.type == EventType.MouseDown)
{
    if (CanShowContextMenu(Selection.activeGameObject))
    {
        ShowContextMenu();    
        Event.current.Use ();
    }
}

右键菜单可以是ContextMenu,可以是PopupWindowContent,其中后者功能更丰富一些:

public class TestContextMenu : UnityEditor.PopupWindowContent
{
    static TestContextMenu menu = new ModuleEditContextMenu();
    public static void Show()
    {
        PopupWindow.Show (new Rect(Event.current.mousePosition, Vector2.zero), menu);

    }
    
    void OnGUI()
    {
        //添加右键菜单内容
    }
}

右键菜单有好多用处,比如我选择了几个ui元素(Selection.gameObjects),可以不是同一个parent,想把他们对齐,同时修改position和pivot,如下图:

[编辑器]Unity的SceneView自定义鼠标事件

很方便。