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,如下图:
很方便。