[Unity]自定义地图编辑器(Scene视图下,EditorWindow的简单应用)
2024-09-06 12:37:32
最近的游戏又很多关卡需要配置(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射线,获取预览
以上~废话结束
最新文章
- mongodb c#语法基础
- 自定义View(9)关于onLayout
- class 类(1)
- JQuery或JavaScript获取网页的宽度、高等
- This application failed to start because it could not find or load the Qt platform plugin ";windows";
- 201521123009 《Java程序设计》第8周学习总结
- @EnableTransactionManagement注解理解
- maven生成项目慢解决办法
- ubuntu安装tensorboardx
- profile default1
- ethereum/EIPs-161 State trie clearing
- <;数据结构与算法分析>;读书笔记--最大子序列和问题的求解
- Star HDU1541
- ldap服务备份与恢复
- 弄清SDI显示工程中的每一个信号,每一个逻辑
- 关于class produre
- LoadIcon
- 用Visual C#来清空回收站(1)
- Android开发中adb命令的常用方法
- Java第二次实验20135204
热门文章
- 真正“搞”懂HTTP协议07之body的玩法(实践篇)
- 用云服务器搭建frp服务(超详细)
- Java程序员用代码,计算最大公约数和最小公倍数
- PyTorch如何加速数据并行训练?分布式秘籍大揭秘
- Pollard_Rho算法
- IO多路复用完全解析
- 论文翻译:2022_PercepNet+: A Phase and SNR Aware PercepNet for Real-Time Speech Enhancement
- wsl 网络探究
- Ajax局部修改页面使用html()内置标签
- H3C MS4300V2配置mac地址与接口绑定