前幾天項目須要就作了個相似於Collider EditCollider的功能編輯器
下面是我作的效果ide
基礎代碼以下:函數
public class ExportCFGInputWindow : EditorWindow { public static ExportCFGInputWindow instance; Vector3 dot1, dot2, dot3, dot4; void OnEnable() { instance = this; SceneView.duringSceneGui -= this.OnSceneGUI; SceneView.duringSceneGui += this.OnSceneGUI; dot1 = new Vector3(0, 0, 0); dot2 = new Vector3(0, 0, 1); dot3 = new Vector3(1, 0, 1); dot4 = new Vector3(1, 0, 0); mid1Cor = Color.green; mid2Cor = Color.green; mid3Cor = Color.green; mid4Cor = Color.green; } void OnDisable() { instance = null; SceneView.duringSceneGui -= this.OnSceneGUI; } void OnSceneGUI(SceneView sceneView) { Handles.color = Color.green; Handles.DrawAAPolyLine(2, dot1, dot2, dot3, dot4, dot1); } }
效果如圖ui
下面是我踩的坑this
先無論先把小綠點畫因而我在OnSceneGui方法裏面插入了以下代碼3d
void OnSceneGUI(SceneView sceneView) { Handles.color = Color.green; Handles.DrawAAPolyLine(2, dot1, dot2, dot3, dot4, dot1); Handles.DotHandleCap(0, new Vector3((dot1.x + dot2.x) * 0.5f, 0, (dot1.z + dot2.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
//0.005f * sceneView.size 的做用是讓小綠點不管你把場景放大或者縮小都是同樣大。
Handles.DotHandleCap(0, new Vector3((dot2.x + dot3.x) * 0.5f, 0, (dot2.z + dot3.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint); Handles.DotHandleCap(0, new Vector3((dot3.x + dot4.x) * 0.5f, 0, (dot3.z + dot4.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint); Handles.DotHandleCap(0, new Vector3((dot4.x + dot1.x) * 0.5f, 0, (dot4.z + dot1.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint); }
這是畫完綠點的樣子blog
雖然有了綠點可是無法控制因而我寫了個方法來監聽鼠標,這個方法在OnSceneGUI函數中調用。具體思路是:綠點的位置知道,只要監聽鼠標在綠點下按下而後移動鼠標,我控制綠點兩端的點跟着鼠標移動就能夠完成了。事件
可是!萬事都怕可是。出現了一個令我頭大的問題:鼠標左鍵的EventType.MouseUp事件我監聽不到(這個問題求好心人幫忙解釋一下。)致使我沒法中止對相應點的控制,固然鼠標中鍵和鼠標右鍵沒有問題,可是鼠標中鍵和鼠標右鍵會在編輯器下有其餘操做。因而我放棄了這個思路。(這裏代碼就不上了)get
既然鼠標不行被逼無奈我就使用了鍵盤控制的方式 ,思路以下:it
4鍵控制上圖最左邊的小綠點,8鍵控制最上面的小綠點,6鍵控制最右面的小綠點,2鍵控制最下面的小綠點。+鍵表示該點向外伸,-鍵表示該點向外內縮。
下面是代碼
int ExportDir = 0;//移動方向
void CheckKey()//這個方法在OnSeneGui函數中調用 { Event e = Event.current; if (e.type == EventType.KeyDown) { if (e.keyCode == KeyCode.Keypad4) { ExportDir = 4; mid1Cor = Color.red; mid2Cor = Color.green; mid3Cor = Color.green; mid4Cor = Color.green; } if (e.keyCode == KeyCode.Keypad6) { ExportDir = 6; mid1Cor = Color.green; mid2Cor = Color.green; mid3Cor = Color.red; mid4Cor = Color.green; } if (e.keyCode == KeyCode.Keypad2) { ExportDir = 2; mid1Cor = Color.green; mid2Cor = Color.green; mid3Cor = Color.green; mid4Cor = Color.red; } if (e.keyCode == KeyCode.Keypad8) { ExportDir = 8; mid1Cor = Color.green; mid2Cor = Color.red; mid3Cor = Color.green; mid4Cor = Color.green; } if (e.keyCode == KeyCode.KeypadPlus) { //ExportDir = 4; Plus(ExportDir); } if (e.keyCode == KeyCode.KeypadMinus) { //ExportDir = 4; Minus(ExportDir); } } }
float EditorSpeed = 0.05f; void Plus(int dir) { if (dir == 4) { dot1.x -= EditorSpeed; dot2.x -= EditorSpeed; } else if (dir == 6) { dot3.x += EditorSpeed; dot4.x += EditorSpeed; } else if (dir == 2) { dot1.z -= EditorSpeed; dot4.z -= EditorSpeed; } else if (dir == 8) { dot2.z += EditorSpeed; dot3.z += EditorSpeed; } else { return; } } void Minus(int dir) { if (dir == 4) { dot1.x += EditorSpeed; dot2.x += EditorSpeed; } else if (dir == 6) { dot3.x -= EditorSpeed; dot4.x -= EditorSpeed; } else if (dir == 2) { dot1.z += EditorSpeed; dot4.z += EditorSpeed; } else if (dir == 8) { dot2.z -= EditorSpeed; dot3.z -= EditorSpeed; } else { return; } }
這樣一來我先按下數字鍵4在按下+鍵最左邊的點就會向左移動了
爲了顯示清楚我還對小綠點顯示顏色左了相應的處理,當選擇哪一個點作動做時它就會變紅,代碼以下
Color mid1Cor = Color.green; Color mid2Cor = Color.green; Color mid3Cor = Color.green; Color mid4Cor = Color.green; void OnSceneGUI(SceneView sceneView) { Handles.color = Color.green; Handles.DrawAAPolyLine(2, dot1, dot2, dot3, dot4, dot1); Handles.color = mid1Cor; Handles.DotHandleCap(0, new Vector3((dot1.x + dot2.x) * 0.5f, 0, (dot1.z + dot2.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint); Handles.color = mid2Cor; Handles.DotHandleCap(0, new Vector3((dot2.x + dot3.x) * 0.5f, 0, (dot2.z + dot3.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint); Handles.color = mid3Cor; Handles.DotHandleCap(0, new Vector3((dot3.x + dot4.x) * 0.5f, 0, (dot3.z + dot4.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint); Handles.color = mid4Cor; Handles.DotHandleCap(0, new Vector3((dot4.x + dot1.x) * 0.5f, 0, (dot4.z + dot1.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint); CheckKey(); }
效果以下:
這個功能也能勉強知足需求,暫時就這樣了。
後來有一天,我發現有人這樣用
Handles.FreeMoveHandle(target.pos,Quaternion.identity,2.0,Vector3.zero,Handles.DrawRectangle);
Handles類的FreeMoveHandle函數我立刻查了一下API發現
public static Vector3 FreeMoveHandle(Vector3 position, Quaternion rotation, float size, Vector3 snap, DrawCapFunction capFunc);
最後一個參數是個委託。我一會兒就明白改怎麼弄了。代碼以下
void OnSceneGUI(SceneView sceneView) { Handles.color = Color.green; Handles.DrawAAPolyLine(2, dot1, dot2, dot3, dot4, dot1); float m1px = Handles.FreeMoveHandle(new Vector3((dot1.x + dot2.x) * 0.5f, 0, (dot1.z + dot2.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).x; dot1 = new Vector3(m1px, 0, dot1.z); dot2 = new Vector3(m1px, 0, dot2.z); float m2px = Handles.FreeMoveHandle(new Vector3((dot2.x + dot3.x) * 0.5f, 0, (dot2.z + dot3.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).z; dot2 = new Vector3(dot2.x, 0, m2px); dot3 = new Vector3(dot3.x, 0, m2px); float m3px = Handles.FreeMoveHandle(new Vector3((dot3.x + dot4.x) * 0.5f, 0, (dot3.z + dot4.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).x; dot3 = new Vector3(m3px, 0, dot3.z); dot4 = new Vector3(m3px, 0, dot4.z); float m4px = Handles.FreeMoveHandle(new Vector3((dot4.x + dot1.x) * 0.5f, 0, (dot4.z + dot1.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).z; dot4 = new Vector3(dot4.x, 0, m4px); dot1 = new Vector3(dot1.x, 0, m4px); }
這樣就達到了我想要的鼠標控制小綠點的效果。可是鍵盤控制的代碼我也保留了,由於我以爲這是個教訓,並且在有時候鍵盤控制也蠻方便的。
完整代碼以下:
public class ExportCFGInputWindow : EditorWindow { public static ExportCFGInputWindow instance; Vector3 dot1, dot2, dot3, dot4; Color mid1Cor, mid2Cor, mid3Cor, mid4Cor; int ExportDir = 0; float EditorSpeed = 0.05f; void OnEnable() { instance = this; SceneView.duringSceneGui -= this.OnSceneGUI; SceneView.duringSceneGui += this.OnSceneGUI; dot1 = new Vector3(0, 0, 0); dot2 = new Vector3(0, 0, 1); dot3 = new Vector3(1, 0, 1); dot4 = new Vector3(1, 0, 0); mid1Cor = Color.green; mid2Cor = Color.green; mid3Cor = Color.green; mid4Cor = Color.green; } void OnDisable() { instance = null; SceneView.duringSceneGui -= this.OnSceneGUI; } Vector3 m1, m2, m3, m4; void OnSceneGUI(SceneView sceneView) { Handles.color = Color.green; Handles.DrawAAPolyLine(2, dot1, dot2, dot3, dot4, dot1); #region 鼠標控制 float m1px = Handles.FreeMoveHandle(new Vector3((dot1.x + dot2.x) * 0.5f, 0, (dot1.z + dot2.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).x; dot1 = new Vector3(m1px, 0, dot1.z); dot2 = new Vector3(m1px, 0, dot2.z); float m2px = Handles.FreeMoveHandle(new Vector3((dot2.x + dot3.x) * 0.5f, 0, (dot2.z + dot3.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).z; dot2 = new Vector3(dot2.x, 0, m2px); dot3 = new Vector3(dot3.x, 0, m2px); float m3px = Handles.FreeMoveHandle(new Vector3((dot3.x + dot4.x) * 0.5f, 0, (dot3.z + dot4.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).x; dot3 = new Vector3(m3px, 0, dot3.z); dot4 = new Vector3(m3px, 0, dot4.z); float m4px = Handles.FreeMoveHandle(new Vector3((dot4.x + dot1.x) * 0.5f, 0, (dot4.z + dot1.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).z; dot4 = new Vector3(dot4.x, 0, m4px); dot1 = new Vector3(dot1.x, 0, m4px); #endregion #region 鍵盤控制 Handles.color = mid1Cor; Handles.DotHandleCap(0, new Vector3((dot1.x + dot2.x) * 0.5f, 0, (dot1.z + dot2.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint); Handles.color = mid2Cor; Handles.DotHandleCap(0, new Vector3((dot2.x + dot3.x) * 0.5f, 0, (dot2.z + dot3.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint); Handles.color = mid3Cor; Handles.DotHandleCap(0, new Vector3((dot3.x + dot4.x) * 0.5f, 0, (dot3.z + dot4.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint); Handles.color = mid4Cor; Handles.DotHandleCap(0, new Vector3((dot4.x + dot1.x) * 0.5f, 0, (dot4.z + dot1.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint); CheckKey(); #endregion } void CheckKey() { Event e = Event.current; if (e.type == EventType.KeyDown) { if (e.keyCode == KeyCode.Keypad4) { ExportDir = 4; mid1Cor = Color.red; mid2Cor = Color.green; mid3Cor = Color.green; mid4Cor = Color.green; } if (e.keyCode == KeyCode.Keypad6) { ExportDir = 6; mid1Cor = Color.green; mid2Cor = Color.green; mid3Cor = Color.red; mid4Cor = Color.green; } if (e.keyCode == KeyCode.Keypad2) { ExportDir = 2; mid1Cor = Color.green; mid2Cor = Color.green; mid3Cor = Color.green; mid4Cor = Color.red; } if (e.keyCode == KeyCode.Keypad8) { ExportDir = 8; mid1Cor = Color.green; mid2Cor = Color.red; mid3Cor = Color.green; mid4Cor = Color.green; } if (e.keyCode == KeyCode.KeypadPlus) { //ExportDir = 4; Plus(ExportDir); } if (e.keyCode == KeyCode.KeypadMinus) { //ExportDir = 4; Minus(ExportDir); } } } void Plus(int dir) { if (dir == 4) { dot1.x -= EditorSpeed; dot2.x -= EditorSpeed; } else if (dir == 6) { dot3.x += EditorSpeed; dot4.x += EditorSpeed; } else if (dir == 2) { dot1.z -= EditorSpeed; dot4.z -= EditorSpeed; } else if (dir == 8) { dot2.z += EditorSpeed; dot3.z += EditorSpeed; } else { return; } } void Minus(int dir) { if (dir == 4) { dot1.x += EditorSpeed; dot2.x += EditorSpeed; } else if (dir == 6) { dot3.x -= EditorSpeed; dot4.x -= EditorSpeed; } else if (dir == 2) { dot1.z += EditorSpeed; dot4.z += EditorSpeed; } else if (dir == 8) { dot2.z -= EditorSpeed; dot3.z -= EditorSpeed; } else { return; } } private void OnGUI() { GUILayout.BeginVertical(); //標籤 GUILayout.BeginHorizontal(); GUILayout.Box("輸入相應的參數", TitleBoxStyle(), GUILayout.Height(60),GUILayout.ExpandWidth(true)); GUILayout.EndHorizontal(); GUILayout.Space(10); GUILayout.BeginHorizontal(); GUIStyle boxStyle = new GUIStyle(); boxStyle.alignment = TextAnchor.MiddleCenter; GUILayout.Box("當前移動速度"+ EditorSpeed, boxStyle, GUILayout.Height(30), GUILayout.Width(80)); GUILayout.Space(10); EditorSpeed = GUILayout.HorizontalSlider(EditorSpeed, 0.01f, 1); GUILayout.EndHorizontal(); GUILayout.EndVertical(); } }
但願此次的分享對你們有點收穫,很差的地方但願你們能幫我指出。