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