[Unity]自定義地圖編輯器(Scene視圖下,EditorWindow的簡單應用)


最近的游戲又很多關卡需要配置(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射線,獲取預覽

以上~廢話結束


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM