最近的游戲又很多關卡需要配置(XML保存),給策划寫了個非常簡單的編輯器,記錄下+廢話下
1:Editor下打開新窗口需要繼承EditorWindow,然后使用獲取窗口即可,注意放在Editor文件夾下
1 public class DrawGameLevel : EditorWindow 2 { 3 [MenuItem("Maps/Creater %M")]//后面快捷鍵 4 public static void OpenMapCreate() 5 { 6 DrawGameLevel window = EditorWindow.GetWindow<DrawGameLevel>("地圖編輯器"); 7 window.Show(); 8 window.minSize = new Vector2(400, 800);//設置最大和最小 9 window.maxSize = new Vector2(400, 1200); 10 } 11 }
2:因為是在Scene視圖下進行操作,所以注冊SceneView.duringSceneGui事件,在OnEnable中
1 void OnEnable() 2 { 3 SceneView.duringSceneGui += OnSceneGUI; 4 //初始化一些東西 5 } 6 7 void OnDestroy() 8 { 9 SceneView.duringSceneGui -= OnSceneGUI; 10 }
3:接着編寫OnSceneGUI,這里首先會替換掉Scene視圖以前的響應事件(就是說在Scene中點擊預制體不再會選擇它了),然后發射射線檢測要繪制的地圖,射線是必須要有碰撞體的,所以在場景中預先准備一個Plane,正對着屏幕,只有射線碰撞到了Plane才會進行繪制
1 private bool _drag = false; 2 void OnSceneGUI(SceneView sceneView) 3 { 4 HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));//為scene響應添加默認事件,用來屏蔽以前的點擊選中物體 5 if (Event.current.type == EventType.MouseDown && Event.current.button == 0)//點擊 6 { 7 } 8 else if (Event.current.type == EventType.MouseUp && Event.current.button == 0)//抬起 9 { 10 if (!_drag) 11 { 12 OnMouseEvent(); 13 } 14 15 _drag = false; 16 } 17 else if (Event.current.type == EventType.MouseDrag && Event.current.button == 0)//拖動 18 { 19 OnMouseEvent(); 20 _drag = true; 21 } 22 } 23 24 private void OnMouseEvent() 25 { 26 Vector2 mousePos = Event.current.mousePosition;//獲取鼠標坐標 27 mousePos.y = Camera.current.pixelHeight - mousePos.y;//這里的鼠標原點在左上,而屏幕空間原點左下,翻轉它 28 //mousePos.y = (float)Screen.height - mousePos.y - 40f;這種寫法也成 29 Ray ray = Camera.current.ScreenPointToRay(mousePos); 30 RaycastHit rh; 31 if (Physics.Raycast(ray, out rh, 3000f)) 32 { 33 //判斷是否射到了plane,是的話進行操作便是 34 } 35 }
4:Scene視圖的處理結束,接着繼續繪制EditorWindow,在OnGUI中繪制
1 string maxRow = String.Empty; 2 string maxCol = string.Empty; 3 private int _select = 0; 4 private Texture[] _items = new Texture[12]; 5 void OnGUI() 6 { 7 maxRow = EditorGUILayout.TextField("Row(最大行數)", maxRow); 8 maxCol = EditorGUILayout.TextField("Col(最大列數)", maxCol); 9 if (GUILayout.Button("開始繪畫")) 10 { 11 //按鈕操作 12 } 13 if (GUILayout.Button("嘗試讀取關卡")) 14 { 15 EditorUtility.DisplayDialog("讀取失敗", "配置文件不存在或者關卡不存在\n讀取失敗,嘗試讀取關卡為:" + _levelNum + "\n請檢查配置文件", "好的");//這個方法可以彈出確認框,返回bool 16 } 17 EditorGUILayout.BeginHorizontal("box"); 18 int sizeY = 100 * Mathf.CeilToInt(_items.Length / 4f); 19 _select = GUI.SelectionGrid(new Rect(new Vector2(0, 155), new Vector2(100 * 4, sizeY)), _select, _items, 4);//可以給出grid選擇框,需要傳入貼圖數組_items 20 }
5:已經結束了,怎么繪制上去的?OnMouseEvent()中發現點擊到了,AssetDataBase.Load生成prefab上去就行,而傳入Grid中的Texture,可以使用AssetPreview.GetAssetPreview(AssetDatabase.LoadAssetAtPath<Object>("path.png")) as Texture;來獲取到預覽圖
最后保存可以自己寫正反解析xml,也可以直接把場景內繪制好的拖成預制體
主要關注的就是 阻止Scene事件,Scene射線,獲取預覽
以上~廢話結束