当前位置:   article > 正文

unity实现简单的地图编辑器,实现跑酷地图编辑器 2d地图编辑器,导出地图json数据,导入地图json数据_unity 地图编辑器

unity 地图编辑器

这里使用的是unity2020.1

对于unity编辑器开发也不是很了解,这方面的教程也不多,也是慢慢摸索的

效果显示

首先简单

介绍下Unity编辑器开发

1:Editor下打开新窗口需要继承EditorWindow,然后使用获取窗口即可,注意放在Editor文件夹下

  1. public class DrawGameLevel : EditorWindow
  2. {
  3. [MenuItem("Maps/Create Map &M")]
  4. public static void OpenMapCreate()
  5. {
  6. DrawGameLevel window = EditorWindow.GetWindow<DrawGameLevel>("地图编辑器");
  7. window.Show();
  8. window.minSize = new Vector2(500, 800);
  9. window.maxSize = new Vector2(600, 1200);
  10. }
  11. }

2:因为是在Scene视图下进行操作,所以注册SceneView.duringSceneGui事件,在OnEnable中

  1. void OnEnable()
  2. 2 {
  3. 3 SceneView.duringSceneGui += OnSceneGUI;
  4. 4 //初始化一些东西
  5. 5 }
  6. 6
  7. 7 void OnDestroy()
  8. 8 {
  9. 9 SceneView.duringSceneGui -= OnSceneGUI;
  10. 10 }

3:unity 编辑器开发,需要在GUI中写,使用EditorGUILayout或者GUILayout来显示ui,基本的组件都是有的

这是我实现的界面和代码  

  1. #region GUI显示
  2. private string brushY = "";// 刷新的y坐标
  3. private string brushX = "";// 刷新的x坐标
  4. private string brushDisY = "0";// 刷新的y坐标间距
  5. private string brushDisX = "0";// 刷新的x坐标间距
  6. private string zIndex = "-0.2";// 显示的层级
  7. private string fixCount = "0";// 固定生成个数,设置0,一直生成
  8. private float _lastBrushY = -10000;// 保持Y合理间距 上次刷的y的坐标
  9. private float _lastBrushX = -10000;// 保持X合理间距 上一个刷的x的坐标
  10. private int _curImgIndex = -1;//当前正在使用的图
  11. private int _curFixCount = 0;// 当前已经生成的个数
  12. private bool _drag = false;// 鼠标拖拽?
  13. private int _select = 0;// 当前选择的图片 index
  14. private string ck = "1";// 关卡
  15. private Texture[] _items = null;// 地形基础图 要使用的地块
  16. private GameObject parentMap = null;// 地图节点的父节点
  17. private GameObject bgParent = null;// 背景图挂点
  18. private string[] bgNames = { "Forest", "Night", "Winter" };// 背景图名字
  19. private int selectMapIndex = 0;// 选择的地图背景图index
  20. private int lastSelectMapIndex = -1;// 上次选择的地图背景图index
  21. private int funcTypeIndex = 0;// 功能类型的index
  22. private string[] funcTypeArry = { "无","橡皮擦","选中单个物体"};// 选择单个物体
  23. private int selectTypeIndex = 0;
  24. private int lastSelectTypeIndex = 0;// 上次选择的类型
  25. private string[] typeArry = {"不显示选图", "地形图","障碍物",};
  26. // Update is called once per frame
  27. void OnGUI()
  28. {
  29. GUI.skin.label.normal.textColor = Color.yellow;
  30. GUI.skin.label.fontSize = 15;
  31. GUIStyle popStyle = new GUIStyle("Popup");
  32. popStyle.fontSize = 15;
  33. // 选择地图
  34. EditorGUILayout.Space();
  35. EditorGUILayout.BeginHorizontal();
  36. GUILayout.Label("1.选择地图", GUILayout.Width(200));
  37. this.selectMapIndex = EditorGUILayout.Popup(this.selectMapIndex, bgNames, popStyle, GUILayout.MaxWidth(100));
  38. EditorGUILayout.EndHorizontal();
  39. EditorGUILayout.Space();
  40. LoadBg();
  41. ck = EditorGUILayout.TextField("2.设置关卡", ck);
  42. // 输入数据
  43. EditorGUILayout.Space();
  44. GUILayout.Label("设置坐标,批量坐标保持一致的时候使用,不输入是按照鼠标位置刷新");
  45. brushY = EditorGUILayout.TextField("3.固定Y的坐标(从左到右刷)", brushY);
  46. brushX = EditorGUILayout.TextField("4.固定X的坐标(从上到下刷)", brushX);
  47. brushDisY = EditorGUILayout.TextField("5.固定Y间距(从左到右刷)", brushDisY);
  48. brushDisX = EditorGUILayout.TextField("6.固定X间距(从上到下刷)", brushDisX);
  49. fixCount = EditorGUILayout.TextField("7.固定生成的个数", fixCount);
  50. EditorGUILayout.Space(10);
  51. zIndex = EditorGUILayout.TextField("8.物体显示层级,小的靠前显示", zIndex);
  52. EditorGUILayout.Space();
  53. EditorGUILayout.BeginHorizontal();
  54. GUILayout.Label("9.选择橡皮擦 或者 选中一个场景物体", GUILayout.Width(250));
  55. this.funcTypeIndex = EditorGUILayout.Popup(this.funcTypeIndex, funcTypeArry, popStyle, GUILayout.MaxWidth(100));
  56. EditorGUILayout.EndHorizontal();
  57. EditorGUILayout.Space();
  58. EditorGUILayout.BeginHorizontal("box");
  59. GUIStyle btnStyle = new GUIStyle("Button");
  60. btnStyle.fontSize = 15;
  61. btnStyle.padding = new RectOffset(10, 10, 10, 10);
  62. if (GUILayout.Button("10.清除当前地图数据",btnStyle))
  63. {
  64. RemoveParentChild(parentMap);
  65. _lastBrushY = -10000;// 防止后面刷新跟着这个位置
  66. _lastBrushX = -10000;
  67. _curFixCount = 0;
  68. }
  69. if (GUILayout.Button("11.导出json数据",btnStyle))
  70. {
  71. DataMgr.Instance.OutFile(parentMap,ck);
  72. EditorUtility.DisplayDialog("导出数据成", "导出关卡数据成功"+ck, "确定");
  73. }
  74. if (GUILayout.Button("12.导入json数据",btnStyle))
  75. {
  76. DataMgr.Instance.ImportFile(parentMap,ck);
  77. EditorUtility.DisplayDialog("导入数据成功","导入关卡数据成功"+ck,"确定");
  78. }
  79. EditorGUILayout.EndHorizontal();
  80. // 选择图片类型
  81. GUILayout.Label("13.显示选图", GUILayout.Width(200));
  82. this.selectTypeIndex = EditorGUILayout.Popup(this.selectTypeIndex,typeArry, popStyle, GUILayout.MaxWidth(100));
  83. if (selectTypeIndex>0) LoadChooseImg();// 加载选图
  84. }
  85. #endregion

 4:unity 编辑器开发,资源加载可以使用Resources,前提是需要把资源放到Editor->Resources中

5:地图文件导出和导入,通过FileStream和LitJson的解析实现的

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using LitJson;
  7. using UnityEngine;
  8. using UnityEditor;
  9. // 障碍物
  10. public class Obstacle
  11. {
  12. public int id;
  13. public string name;
  14. public int type;
  15. }
  16. // 导出的地图json文件数据格式
  17. public class DataFile
  18. {
  19. public int id;
  20. public string name; // 预制体名字
  21. public string path; // 加载路径
  22. public string tag;// 预制体的tag
  23. public string posX;// 坐标x
  24. public string posY;// 坐标y
  25. public string posZ;// 坐标z
  26. public string scaX;// scale x
  27. public string scaY;// scale y
  28. public string scaZ;// scale z
  29. public string rotX;// rotate x
  30. public string rotY;// rotate y
  31. public string rotZ;// rotate z
  32. // Todo,后面还可以加障碍物id,用于实现障碍物的功能
  33. public DataFile() { }
  34. public DataFile(int id1,string path1,string tag1, float px, float py, float pz, float sx, float sy, float sz, float rx, float ry, float rz)
  35. {
  36. id = id1;
  37. path = path1;
  38. string[] p = path.Split('/');
  39. name = p[p.Length - 1];
  40. tag = tag1;
  41. posX = px.ToString();
  42. posY = py.ToString();
  43. posZ = pz.ToString(); // 使用string类型,是因为转json不识别float和double
  44. scaX = sx.ToString();
  45. scaY = sy.ToString();
  46. scaZ = sz.ToString();
  47. rotX = rx.ToString();
  48. rotY = ry.ToString();
  49. rotZ = rz.ToString();
  50. }
  51. }
  52. public class DataMgr:Editor
  53. {
  54. private static DataMgr instance = null;
  55. public static DataMgr Instance
  56. {
  57. get
  58. {
  59. if (null == instance) instance = new DataMgr();
  60. return instance;
  61. }
  62. }
  63. public readonly List<Obstacle> m_table = null;
  64. public DataMgr()
  65. {
  66. // 注册json类型转换方法
  67. LitJson.JsonMapper.RegisterImporter<int, string>((int input) => { return input.ToString(); });
  68. LitJson.JsonMapper.RegisterImporter<string, int>((string input) => { return Convert.ToInt32(input); });
  69. // 加载障碍物表
  70. //TextAsset ts = Resources.Load<TextAsset>("jsonTable/config_obstacle");
  71. //m_table = JsonMapper.ToObject<List<Obstacle>>(ts.text);
  72. }
  73. // 导出文件json
  74. // ck 关卡id
  75. public void OutFile(GameObject parent,string ck)
  76. {
  77. int childCount = parent.transform.childCount;
  78. if (childCount <= 0)
  79. {
  80. Debug.Log("没有可以导出的数据节点");
  81. }
  82. List<DataFile> list = new List<DataFile>();
  83. for (int i = 0; i < childCount; i++)
  84. {
  85. GameObject obj = parent.transform.GetChild(i).gameObject;
  86. DataFile file = new DataFile(i+1,obj.name,obj.tag,obj.transform.localPosition.x, obj.transform.localPosition.y, obj.transform.localPosition.z, obj.transform.localScale.x, obj.transform.localScale.y,
  87. obj.transform.localScale.z, obj.transform.localRotation.x, obj.transform.localRotation.y,obj.transform.localRotation.z);
  88. list.Add(file);
  89. }
  90. string jsons = JsonMapper.ToJson(list);
  91. FileStream fs = new FileStream(Application.dataPath + "/OutMap/mapCk_"+ck+".json", FileMode.Create);
  92. //存储时时二进制,所以这里需要把我们的字符串转成二进制
  93. byte[] bytes = new UTF8Encoding().GetBytes(jsons);
  94. fs.Write(bytes, 0, bytes.Length);
  95. //每次读取文件后都要记得关闭文件
  96. fs.Close();
  97. Debug.Log("导出成功"+ "/OutMap/mapCk_"+ck +".json");
  98. }
  99. // 导入文件 实例化数据
  100. public void ImportFile(GameObject parent,string ck)
  101. {
  102. if (!parent) return;
  103. FileStream fs = new FileStream(Application.dataPath + "/OutMap/mapCk_" + ck + ".json", FileMode.Open);
  104. byte[] bytes = new byte[fs.Length];
  105. fs.Read(bytes, 0, bytes.Length);
  106. //将读取到的二进制转换成字符串
  107. string s = new UTF8Encoding().GetString(bytes);
  108. List<DataFile> list = JsonMapper.ToObject<List<DataFile>>(s);
  109. if (list.Count <= 0)
  110. {
  111. Debug.Log("没有可导入的数据" + "/OutMap/mapCk_" + ck + ".json");
  112. return;
  113. }
  114. UnityEngine.Object a = Resources.Load<GameObject>(list[0].path);
  115. for (int i = 0; i < list.Count; i++)
  116. {
  117. if (a.name != list[i].path)
  118. {// 实例化新的
  119. a = Resources.Load<GameObject>(list[i].path);
  120. }
  121. GameObject obj = Instantiate(a) as GameObject;
  122. obj.tag = list[i].tag;
  123. obj.name = list[i].path;
  124. obj.transform.parent = parent.transform;
  125. obj.transform.localPosition = new Vector3(Convert.ToSingle(list[i].posX), Convert.ToSingle(list[i].posY), Convert.ToSingle(list[i].posZ));
  126. obj.transform.localRotation = Quaternion.Euler(Convert.ToSingle(list[i].rotX), Convert.ToSingle(list[i].rotY), Convert.ToSingle(list[i].rotZ));
  127. obj.transform.localScale = new Vector3(Convert.ToSingle(list[i].scaX), Convert.ToSingle(list[i].scaY), Convert.ToSingle(list[i].scaZ));
  128. }
  129. Debug.Log("导入成功" + "/OutMap/mapCk_" + ck + ".json");
  130. }
  131. }

6:地图编辑器面版的全部代码

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using UnityEditor.SceneManagement;
  6. using System;
  7. public class DrawGameLevel : EditorWindow
  8. {
  9. [MenuItem("Maps/Create Map &M")]
  10. public static void OpenMapCreate()
  11. {
  12. DrawGameLevel window = EditorWindow.GetWindow<DrawGameLevel>("地图编辑器");
  13. window.Show();
  14. window.minSize = new Vector2(500, 800);
  15. window.maxSize = new Vector2(600, 1200);
  16. }
  17. #region 初始化和关闭界面
  18. private void OnEnable()
  19. {
  20. // 在scene下操作,所以要注册,屏蔽scene原有事件
  21. SceneView.duringSceneGui += OnSceneGUI;
  22. InitUI();
  23. }
  24. private void OnDestroy()
  25. {
  26. // 取消事件,恢复scene
  27. SceneView.duringSceneGui -= OnSceneGUI;
  28. EndUI();
  29. }
  30. //初始化ui,判断是否需要创建挂点
  31. private void InitUI()
  32. {
  33. bgParent = GameObject.Find("BgCamera");
  34. // 判断有没有quad平面
  35. GameObject pa = GameObject.Find("Quad");
  36. if (!pa)
  37. {
  38. GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Quad);
  39. obj.transform.localScale = new Vector3(1000, 10, 1);
  40. obj.transform.position = new Vector3(0, 0, 0);
  41. pa = obj;
  42. }
  43. pa.tag = "Plane";
  44. // 判断地图的父节点 要刷的地形的父节点
  45. GameObject map = GameObject.Find("MapInfo");
  46. if (!map)
  47. {
  48. map = new GameObject("MapInfo");
  49. map.transform.position = Vector3.zero;
  50. }
  51. parentMap = map;
  52. }
  53. // 关闭界面的时候
  54. private void EndUI()
  55. {
  56. // 删除背景图
  57. RemoveParentChild(bgParent);
  58. // 保存数据道json 再
  59. //DataMgr.Instance.OutFile(parentMap,ck);
  60. // 删除parentMap下的
  61. RemoveParentChild(parentMap);
  62. // 保存场景 原始场景
  63. EditorSceneManager.SaveScene(UnityEngine.SceneManagement.SceneManager.GetActiveScene());
  64. }
  65. #endregion
  66. #region 点击事件和射线检测刷地形
  67. private void OnSceneGUI(SceneView sceneView)
  68. {
  69. // 替换Scene视图以前的相应事件,发射线检测要绘制的地图,射线必须要要有碰撞体,所以在场景中准备一个plane,整对着屏幕,只要射线碰撞到plane才进行绘制
  70. HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));// 添加默认响应,来屏蔽以前的
  71. if (Event.current.type == EventType.MouseDown && Event.current.button == 0)// 点击
  72. {
  73. }
  74. else if (Event.current.type == EventType.MouseUp && Event.current.button == 0)// 抬起
  75. {
  76. if (!_drag)
  77. {
  78. OnMouseEvent();
  79. }
  80. _drag = false;
  81. // 清楚上次记录的 拖动位置,上次记录的刷出数量
  82. _lastBrushY = -10000;
  83. _lastBrushX = -10000;
  84. _curFixCount = 0;
  85. }
  86. else if (Event.current.type == EventType.MouseDrag && Event.current.button == 0)
  87. {
  88. OnMouseEvent();
  89. _drag = true;
  90. }
  91. }
  92. // 检测射线
  93. private void OnMouseEvent()
  94. {
  95. Vector2 mousePos = Event.current.mousePosition;
  96. mousePos.y = Camera.current.pixelHeight - mousePos.y;// 这里的鼠标原点在左上,而屏幕空间原点在左下,翻转他
  97. Ray ray = Camera.current.ScreenPointToRay(mousePos);
  98. RaycastHit hit;
  99. if (Physics.Raycast(ray, out hit, 3000f))
  100. {
  101. // 检测是不是要选中一个已经铺设的物体
  102. if (this.funcTypeIndex == 2)
  103. {// 选择了铺设的地图点
  104. if (hit.transform.parent == parentMap.transform)
  105. {// 选中场景中物体
  106. EditorGUIUtility.PingObject(hit.transform);
  107. Selection.activeGameObject = hit.transform.gameObject;
  108. }
  109. return ;
  110. }
  111. // 固定生成的个数够了,不生成了
  112. if (Convert.ToInt32(fixCount) > 0 && Convert.ToInt32(fixCount) <= _curFixCount) return;
  113. //
  114. if ((hit.transform.tag == "Plane" || hit.transform.tag == "Ground") && this.funcTypeIndex!=1)
  115. {// 实例化图 点击的是地面,或者点击的是ground
  116. GameObject obj = GetBrushName();
  117. float x = 0;// 这里使用临时的,是为了防止引用变量带来的错误
  118. float y = 0;
  119. Vector3 pos = Camera.current.ScreenToWorldPoint(mousePos);
  120. if (brushX != "")
  121. {// x一致 刷的物体 ,记录本次的y坐标,下次方便调整间距
  122. pos.x = Convert.ToSingle(brushX);
  123. if (_lastBrushY != -10000)
  124. {// 前面有刷的同物体,计算本次位置
  125. var box = obj.GetComponent<BoxCollider>();
  126. if (box)
  127. {// 必须从上往下刷
  128. _lastBrushY -= (box.size.y * obj.transform.localScale.y) + Convert.ToSingle(brushDisY);
  129. y = _lastBrushY;
  130. }
  131. }
  132. else _lastBrushY = pos.y;
  133. }
  134. else if (brushY != "")
  135. {// 刷的物体y一致 ,记录本次的x坐标,下次方便调整间距
  136. pos.y = Convert.ToSingle(brushY);
  137. if (_lastBrushX != -10000)
  138. {// 前面有刷的同物体,计算本次位置
  139. var box = obj.GetComponent<BoxCollider>();
  140. if (box)
  141. {// 必须从左往右刷
  142. _lastBrushX += box.size.x * obj.transform.localScale.x + Convert.ToSingle(brushDisX);
  143. x = _lastBrushX;
  144. }
  145. }
  146. else _lastBrushX = pos.x;
  147. }
  148. obj.transform.localPosition = new Vector3(x != 0 ? x : pos.x, y != 0 ? y : pos.y,Convert.ToSingle(zIndex));
  149. if (Convert.ToInt32(fixCount) > 0 && (brushY != "" || brushX != ""))
  150. {// 有刷x或者y,并且固定个数,数量加
  151. _curFixCount++;
  152. }
  153. }
  154. else if ((hit.transform.tag == "Ground" || hit.transform.tag == "Obstacle") && this.funcTypeIndex == 1)
  155. {// 选择了橡皮擦,擦除地面 或者 障碍物
  156. UnityEngine.Object.DestroyImmediate(hit.transform.gameObject);
  157. }
  158. }
  159. }
  160. #endregion
  161. #region GUI显示
  162. private string brushY = "";// 刷新的y坐标
  163. private string brushX = "";// 刷新的x坐标
  164. private string brushDisY = "0";// 刷新的y坐标间距
  165. private string brushDisX = "0";// 刷新的x坐标间距
  166. private string zIndex = "-0.2";// 显示的层级
  167. private string fixCount = "0";// 固定生成个数,设置0,一直生成
  168. private float _lastBrushY = -10000;// 保持Y合理间距 上次刷的y的坐标
  169. private float _lastBrushX = -10000;// 保持X合理间距 上一个刷的x的坐标
  170. private int _curImgIndex = -1;//当前正在使用的图
  171. private int _curFixCount = 0;// 当前已经生成的个数
  172. private bool _drag = false;// 鼠标拖拽?
  173. private int _select = 0;// 当前选择的图片 index
  174. private string ck = "1";// 关卡
  175. private Texture[] _items = null;// 地形基础图 要使用的地块
  176. private GameObject parentMap = null;// 地图节点的父节点
  177. private GameObject bgParent = null;// 背景图挂点
  178. private string[] bgNames = { "Forest", "Night", "Winter" };// 背景图名字
  179. private int selectMapIndex = 0;// 选择的地图背景图index
  180. private int lastSelectMapIndex = -1;// 上次选择的地图背景图index
  181. private int funcTypeIndex = 0;// 功能类型的index
  182. private string[] funcTypeArry = { "无","橡皮擦","选中单个物体"};// 选择单个物体
  183. private int selectTypeIndex = 0;
  184. private int lastSelectTypeIndex = 0;// 上次选择的类型
  185. private string[] typeArry = {"不显示选图", "地形图","障碍物",};
  186. // Update is called once per frame
  187. void OnGUI()
  188. {
  189. GUI.skin.label.normal.textColor = Color.yellow;
  190. GUI.skin.label.fontSize = 15;
  191. GUIStyle popStyle = new GUIStyle("Popup");
  192. popStyle.fontSize = 15;
  193. // 选择地图
  194. EditorGUILayout.Space();
  195. EditorGUILayout.BeginHorizontal();
  196. GUILayout.Label("1.选择地图", GUILayout.Width(200));
  197. this.selectMapIndex = EditorGUILayout.Popup(this.selectMapIndex, bgNames, popStyle, GUILayout.MaxWidth(100));
  198. EditorGUILayout.EndHorizontal();
  199. EditorGUILayout.Space();
  200. LoadBg();
  201. ck = EditorGUILayout.TextField("2.设置关卡", ck);
  202. // 输入数据
  203. EditorGUILayout.Space();
  204. GUILayout.Label("设置坐标,批量坐标保持一致的时候使用,不输入是按照鼠标位置刷新");
  205. brushY = EditorGUILayout.TextField("3.固定Y的坐标(从左到右刷)", brushY);
  206. brushX = EditorGUILayout.TextField("4.固定X的坐标(从上到下刷)", brushX);
  207. brushDisY = EditorGUILayout.TextField("5.固定Y间距(从左到右刷)", brushDisY);
  208. brushDisX = EditorGUILayout.TextField("6.固定X间距(从上到下刷)", brushDisX);
  209. fixCount = EditorGUILayout.TextField("7.固定生成的个数", fixCount);
  210. EditorGUILayout.Space(10);
  211. zIndex = EditorGUILayout.TextField("8.物体显示层级,小的靠前显示", zIndex);
  212. EditorGUILayout.Space();
  213. EditorGUILayout.BeginHorizontal();
  214. GUILayout.Label("9.选择橡皮擦 或者 选中一个场景物体", GUILayout.Width(250));
  215. this.funcTypeIndex = EditorGUILayout.Popup(this.funcTypeIndex, funcTypeArry, popStyle, GUILayout.MaxWidth(100));
  216. EditorGUILayout.EndHorizontal();
  217. EditorGUILayout.Space();
  218. EditorGUILayout.BeginHorizontal("box");
  219. GUIStyle btnStyle = new GUIStyle("Button");
  220. btnStyle.fontSize = 15;
  221. btnStyle.padding = new RectOffset(10, 10, 10, 10);
  222. if (GUILayout.Button("10.清除当前地图数据",btnStyle))
  223. {
  224. RemoveParentChild(parentMap);
  225. _lastBrushY = -10000;// 防止后面刷新跟着这个位置
  226. _lastBrushX = -10000;
  227. _curFixCount = 0;
  228. }
  229. if (GUILayout.Button("11.导出json数据",btnStyle))
  230. {
  231. DataMgr.Instance.OutFile(parentMap,ck);
  232. EditorUtility.DisplayDialog("导出数据成", "导出关卡数据成功"+ck, "确定");
  233. }
  234. if (GUILayout.Button("12.导入json数据",btnStyle))
  235. {
  236. DataMgr.Instance.ImportFile(parentMap,ck);
  237. EditorUtility.DisplayDialog("导入数据成功","导入关卡数据成功"+ck,"确定");
  238. }
  239. EditorGUILayout.EndHorizontal();
  240. // 选择图片类型
  241. GUILayout.Label("13.显示选图", GUILayout.Width(200));
  242. this.selectTypeIndex = EditorGUILayout.Popup(this.selectTypeIndex,typeArry, popStyle, GUILayout.MaxWidth(100));
  243. if (selectTypeIndex>0) LoadChooseImg();// 加载选图
  244. }
  245. #endregion
  246. #region 加载图片和删除
  247. // 加载地形需要图 选择使用
  248. private void LoadChooseImg()
  249. {
  250. // 根据类型,加载相应地形图,障碍,还是金币,还是基础地形
  251. string name = bgNames[this.selectMapIndex].ToLower();
  252. switch (selectTypeIndex)
  253. {
  254. case 2:name = "obstacle";break;
  255. case 3:name = "gold"; break;
  256. }
  257. Texture[] ts = Resources.LoadAll<Texture>("baseImg/" + name);
  258. if (ts.Length<=0) return;// 无图
  259. _items = ts;
  260. int sizeY = 100 * Mathf.CeilToInt(_items.Length / 5f);
  261. _select = GUI.SelectionGrid(new Rect(new Vector2(0, 385), new Vector2(100 * 5, sizeY)), _select, _items, 5); //可以给出grid选择框,需要传入贴图数组_items
  262. if (_select != _curImgIndex || lastSelectTypeIndex != selectTypeIndex)
  263. {// 切换图片了,清楚上次使用的同时刷的最后一个物体的x y 记录的刷出来的固定数量
  264. lastSelectTypeIndex = selectTypeIndex;
  265. _curImgIndex = _select;
  266. _lastBrushY = -10000;
  267. _lastBrushX = -10000;
  268. _curFixCount = 0;
  269. }
  270. }
  271. // 加载背景图
  272. private void LoadBg()
  273. {
  274. if (lastSelectMapIndex == selectMapIndex) return;
  275. if (!bgParent) return;
  276. lastSelectMapIndex = selectMapIndex;
  277. RemoveParentChild(bgParent);// 删除之前的背景
  278. RemoveParentChild(parentMap);// 删除之前铺设的
  279. int dis = 19;//间距 根据实际背景图算的
  280. UnityEngine.Object a = Resources.Load<GameObject>("Prefabs/" + bgNames[selectMapIndex]);
  281. for (int i = 0; i < 100; i++)
  282. {
  283. GameObject o1 = Instantiate(a) as GameObject;
  284. o1.transform.parent = bgParent.transform;
  285. o1.transform.localPosition = new Vector3(-488 + dis * i, o1.transform.position.y, o1.transform.position.z);
  286. // -488是根据实际的quad的长度一半得到的
  287. }
  288. }
  289. // 获取要刷的图片
  290. private GameObject GetBrushName()
  291. {
  292. string tag = "Ground";// 设置物体的tag
  293. string name = bgNames[this.selectMapIndex].ToLower();
  294. switch (selectTypeIndex)
  295. {
  296. case 2: name = "obstacle"; tag = "Obstacle"; break;
  297. case 3: name = "gold"; tag = "Gold"; break;
  298. }
  299. name = "Prefabs_block/" + name + "/" + _items[_select].name;
  300. UnityEngine.Object a = Resources.Load<GameObject>(name);
  301. GameObject obj = Instantiate(a) as GameObject;
  302. obj.tag = tag;
  303. obj.name = name;
  304. obj.transform.parent = parentMap.transform;
  305. return obj;
  306. }
  307. // 删除父节点的所有子
  308. private void RemoveParentChild(GameObject parent)
  309. {
  310. if (parent)
  311. {
  312. while (parent.transform.childCount > 0)
  313. {
  314. UnityEngine.Object.DestroyImmediate(parent.transform.GetChild(0).gameObject);
  315. }
  316. }
  317. }
  318. #endregion
  319. private void Update()
  320. {
  321. if (this.funcTypeIndex != 2)// 点击
  322. {// 不单独选择,那就把选择取消,取消编辑器的选中物体
  323. EditorGUIUtility.PingObject(null);
  324. Selection.activeGameObject = null;
  325. }
  326. // 修改鼠标样式
  327. //if(_items!=null) Cursor.SetCursor(_items[_select] as Texture2D, Vector2.zero, CursorMode.Auto);
  328. }
  329. }

项目github地址:https://github.com/SuiFengErQu/unity----map-Editor

参考:https://www.cnblogs.com/wayneWy/p/13087940.html

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/784087
推荐阅读
相关标签
  

闽ICP备14008679号