[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射线,获取预览

以上~废话结束

posted @ 2020-06-10 19:16  wayneWy  阅读(2890)  评论(0编辑  收藏  举报