打算寫這樣一個工具,可用於影片鏡頭調節,房產漫游的可視化,建立多個可視鏡頭,可以動態調整各個鏡頭的位置和旋轉方向,同時,還能在類似於Camera 的Preview這樣的小窗口中查看該鏡頭(在小窗口中點擊鼠標左鍵並拖拽能調節鏡頭的旋轉軸向),示意圖如下:
首先,第一步:創建一個腳本,公開兩個參數(目前功能還有待豐富,后續更新...)
第二步:創建一個Editor腳本,開始在里面編輯內容,previewCamera即在小窗口中看到的Camera,將這個Camera看到的畫面DrawCamera到SceneGUI即可實時預覽
若不添加可編輯多個
第三步:創建一個Camera的Component,讓它的HideFlags設置為隱藏,previewCamera.enable是設置它是否在game窗口中可見,這里我們把它設為false,讓它只在Scene窗口中可見。
第四步:在Scene窗口中繪制你的Camera鏡頭,判斷鼠標是否在小窗口內,然后判斷是否按下鼠標左鍵和是否拖拽,然后畫面就會根據鼠標拖拽的增量來改變鏡頭的rotation。
其中要注意的是:判斷EventType為Repaint,再DrawCamera,不然該物體在Scene中不能用鼠標拖拽改變它的position。
第五步:重寫OnInspectorGUI,繪制你的Inspector面板,將前面定義的兩個屬性加上,一個為是否開啟Preview功能,另一個為你的鏡頭名稱,鏡頭名稱將直接顯示在小窗口的最頂端。
第六步:最后在OnDisable的時候,若預覽相機不為空,就將它刪除掉,單一管理避免重復。
附上完整代碼:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using UnityEditor; 5 using UnityEngine; 6 7 [CustomEditor(typeof(Preview)),CanEditMultipleObjects] 8 public class PreviewEditor : Editor { 9 10 private Camera previewCamera; 11 private bool isEditingMultipleObjects = false; 12 13 void OnEnable() 14 { 15 if (this.previewCamera != null) 16 { 17 UnityEngine.Object.DestroyImmediate(this.previewCamera.gameObject); 18 } 19 System.Type[] components = new System.Type[] { typeof(Camera) }; 20 this.previewCamera = EditorUtility.CreateGameObjectWithHideFlags("Preview cam", HideFlags.HideAndDontSave, components).GetComponent<Camera>(); 21 this.previewCamera.farClipPlane = 10000f; 22 this.previewCamera.enabled = false; 23 24 } 25 private void OnSceneGUI() 26 { 27 if (!this.isEditingMultipleObjects) 28 { 29 Preview pv = (Preview)target; 30 this.previewCamera.transform.position = pv.transform.position; 31 this.previewCamera.transform.rotation = pv.transform.rotation; 32 if (pv.SetPreview) 33 { 34 Handles.BeginGUI(); 35 Rect position = SceneView.currentDrawingSceneView.position; 36 position.x = position.width - 300f; 37 position.y = (position.height - 180f) - 20f; 38 position.width = 294f; 39 position.height = 174f; 40 Event current = Event.current; 41 42 if (position.Contains(current.mousePosition)) 43 { 44 if ((current.button == 0) && (current.type == EventType.MouseDrag)) 45 { 46 pv.transform.localEulerAngles = new Vector3(pv.transform.localEulerAngles.x + current.delta.y * 0.5f, pv.transform.localEulerAngles.y + current.delta.x * 0.2f, 0); 47 current.Use(); 48 } 49 } 50 51 GUI.Button(new Rect(position.x - 6, position.y - 8, position.width + 10, position.height + 10), pv.textField.ToString(), GUI.skin.window); 52 53 if (Event.current.type == EventType.Repaint) 54 { 55 Handles.DrawCamera(position, this.previewCamera); 56 } 57 Handles.EndGUI(); 58 } 59 } 60 61 } 62 63 public override void OnInspectorGUI() 64 { 65 if (SceneView.currentDrawingSceneView != null) 66 { 67 SceneView.currentDrawingSceneView.Repaint(); 68 } 69 base.serializedObject.Update(); 70 Preview preview = (Preview)target; 71 preview.SetPreview = EditorGUILayout.Toggle("Preview", preview.SetPreview); 72 preview.textField = EditorGUILayout.TextField("請設置您的鏡頭名稱:", preview.textField); 73 74 this.isEditingMultipleObjects = base.serializedObject.isEditingMultipleObjects; 75 76 } 77 private void OnDisable() 78 { 79 if (this.previewCamera != null) 80 { 81 UnityEngine.Object.DestroyImmediate(this.previewCamera.gameObject); 82 } 83 } 84 }