打算写这样一个工具,可用于影片镜头调节,房产漫游的可视化,建立多个可视镜头,可以动态调整各个镜头的位置和旋转方向,同时,还能在类似于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 }