using System.IO; using UnityEditor; using UnityEngine; namespace H2Engine { [CustomEditor(typeof(Bhv_MapData))] public class MapEditor : Editor { private string LS_KEY_SAVEPATH; private string LS_KEY_EXPORTPATH; private Evt.E_EventType eventType = Evt.E_EventType.Enemy; [MenuItem("程序/MapEditor | 地图编辑器")] static void Init() { var _mono = GameObject.FindObjectOfType(); if (_mono == null) { var _root = CreateNewGO(Bhv_MapData.NodeName_Root); _mono = _root.AddComponent(); Selection.activeGameObject = _root; var _child = CreateNewGO(Bhv_MapData.NodeName_TriggerList); _child.transform.SetParent(_root.transform); _child = CreateNewGO(Bhv_MapData.NodeName_EventList); _child.transform.SetParent(_root.transform); _child = CreateNewGO(Bhv_MapData.NodeName_TransferList); _child.transform.SetParent(_root.transform); var _goes = FindObjectsOfType(typeof(GameObject)) as GameObject[]; foreach (var _go in _goes) { if (_go.layer == LayerUtility.Walkble) { _root.AddComponent().sharedMesh = _go.GetComponent().sharedMesh; _root.AddComponent(); _root.transform.position = _go.transform.position; _root.transform.rotation = _go.transform.rotation; _root.transform.localScale = _go.transform.localScale; _root.layer = LayerUtility.Walkble; break; } } } } public static GameObject CreateNewGO(string name) { var _go = new GameObject(name); _go.transform.position = Vector3.zero; _go.transform.eulerAngles = Vector3.zero; _go.transform.localScale = Vector3.one; return _go; } private GUISkin gUISkin; /// /// This function is called when the object becomes enabled and active. /// void OnEnable() { target.name = "MapEditor"; LS_KEY_SAVEPATH = System.Environment.CurrentDirectory + "/MapEditor/Save"; LS_KEY_EXPORTPATH = System.Environment.CurrentDirectory + "/MapEditor/Export"; EffectConfig.Init(); } public override void OnInspectorGUI() { if (GUILayout.Button("测试")) { // Debug.Log("1 & 2 = " + (1 & 2)); var _center = Vector3.zero; int _count = 18; int _dropCount = 0; while (_dropCount < _count) { var _cube = GameObject.CreatePrimitive(PrimitiveType.Cube); _dropCount += 1; } } if (gUISkin == null) { gUISkin = AssetDatabase.LoadAssetAtPath("Assets/Scripts/Core/MapEditor/Editor/EditorResources/EditorSkin.guiskin"); } serializedObject.Update(); var _mapData = target as Bhv_MapData; GUILayout.Space(5); EditorGUILayout.BeginVertical(gUISkin.box); EditorGUILayout.BeginHorizontal(gUISkin.box, GUILayout.Height(24)); EditorGUILayout.LabelField("数据ID", gUISkin.customStyles[0], GUILayout.Height(22), GUILayout.Width(60)); _mapData.id = EditorGUILayout.IntField(_mapData.id, gUISkin.textField, GUILayout.Height(22)); if (GUILayout.Button("加载", gUISkin.button, GUILayout.Width(60), GUILayout.Height(22))) { LoadJson(); } if (GUILayout.Button("保存", gUISkin.button, GUILayout.Width(60), GUILayout.Height(22))) { SaveJson(); } if (GUILayout.Button("导出", gUISkin.button, GUILayout.Width(60), GUILayout.Height(22))) { Export(); } // if (GUILayout.Button("导入", gUISkin.button, GUILayout.Width(60), GUILayout.Height(22))) // { // MapData.LoadFormFile(10010); // } EditorGUILayout.EndHorizontal(); /// -------------------------------------------------------------------------------- /// 触发器列表 Start EditorGUILayout.BeginVertical(gUISkin.box); EditorGUILayout.BeginHorizontal(GUILayout.Height(22)); EditorGUI.indentLevel += 1; if (_mapData.triggerList.Count > 0) { _mapData.showTriggerList = EditorGUILayout.Foldout(_mapData.showTriggerList, " 触发器列表", true, gUISkin.customStyles[3]); } else { EditorGUILayout.LabelField("触发器列表", gUISkin.customStyles[0], GUILayout.Height(22), GUILayout.Width(100)); GUILayout.FlexibleSpace(); } EditorGUI.indentLevel -= 1; if (GUILayout.Button("添加", gUISkin.button, GUILayout.Width(60), GUILayout.Height(22))) { CreateTrigger(); _mapData.showTriggerList = true; } EditorGUILayout.EndHorizontal(); if (_mapData.showTriggerList) { for (int i = _mapData.triggerList.Count - 1; i >= 0; --i) { var _trigger = _mapData.triggerList[i]; if (_trigger == null) { _mapData.triggerList.RemoveAt(i); continue; } if (_trigger.DrawUI(gUISkin)) { _mapData.triggerList.RemoveAt(i); DestroyImmediate(_trigger.gameObject); } } } EditorGUILayout.EndVertical(); /// 触发器列表 End /// -------------------------------------------------------------------------------- /// -------------------------------------------------------------------------------- /// 事件列表 Start EditorGUILayout.BeginVertical(gUISkin.box); EditorGUILayout.BeginHorizontal(GUILayout.Height(22)); EditorGUI.indentLevel += 1; if (_mapData.eventList.Count > 0) { _mapData.showEventList = EditorGUILayout.Foldout(_mapData.showEventList, " 事件列表", true, gUISkin.customStyles[3]); } else { EditorGUILayout.LabelField("事件列表", gUISkin.customStyles[0], GUILayout.Height(22), GUILayout.Width(100)); GUILayout.FlexibleSpace(); } EditorGUI.indentLevel -= 1; eventType = (Evt.E_EventType)EditorGUILayout.EnumPopup(eventType, gUISkin.customStyles[1], GUILayout.Height(22), GUILayout.Width(100)); if (GUILayout.Button("添加", gUISkin.button, GUILayout.Width(60), GUILayout.Height(22))) { CreateEvent(eventType); _mapData.showEventList = true; } EditorGUILayout.EndHorizontal(); if (_mapData.showEventList) { for (int i = _mapData.eventList.Count - 1; i >= 0; --i) { var _event = _mapData.eventList[i]; if (_event == null) { _mapData.eventList.RemoveAt(i); continue; } if (_event.DrawUI(gUISkin)) { _mapData.eventList.RemoveAt(i); DestroyImmediate(_event.gameObject); } } } EditorGUILayout.EndVertical(); /// 事件列表 End /// -------------------------------------------------------------------------------- /// -------------------------------------------------------------------------------- /// 传送点列表 Start EditorGUILayout.BeginVertical(gUISkin.box); EditorGUILayout.BeginHorizontal(GUILayout.Height(22)); EditorGUI.indentLevel += 1; if (_mapData.transferList.Count > 0) { _mapData.showTransferList = EditorGUILayout.Foldout(_mapData.showTransferList, " 传送组列表", true, gUISkin.customStyles[3]); } else { EditorGUILayout.LabelField("传送组列表", gUISkin.customStyles[0], GUILayout.Height(22), GUILayout.Width(100)); GUILayout.FlexibleSpace(); } EditorGUI.indentLevel -= 1; if (GUILayout.Button("添加", gUISkin.button, GUILayout.Width(60), GUILayout.Height(22))) { CreateTransferPoint(); _mapData.showTransferList = true; } EditorGUILayout.EndHorizontal(); if (_mapData.showTransferList) { for (int i = _mapData.transferList.Count - 1; i >= 0; --i) { var _transfer = _mapData.transferList[i]; if (_transfer == null) { _mapData.transferList.RemoveAt(i); continue; } if (_transfer.DrawUI(_mapData, gUISkin)) { _mapData.transferList.RemoveAt(i); DestroyImmediate(_transfer.gameObject); } } } EditorGUILayout.EndVertical(); /// 传送点列表 End /// -------------------------------------------------------------------------------- /// -------------------------------------------------------------------------------- /// 场景物件列表 Start /// 场景物件列表 End /// -------------------------------------------------------------------------------- EditorGUILayout.EndVertical(); if (GUI.changed) { EditorUtility.SetDirty(target); serializedObject.ApplyModifiedProperties(); } } private void CreateTrigger() { var _mapData = target as Bhv_MapData; var _id = _mapData.RequestTriggerID(); var _trigger = CreateNewGO(Bhv_MapData.NodeName_Trigger + _id); var _triggerBhv = _trigger.AddComponent(); _triggerBhv.id = _id; _triggerBhv.boxCollider = _trigger.AddComponent(); _trigger.transform.SetParent(_mapData.transform.Find(Bhv_MapData.NodeName_TriggerList)); _mapData.triggerList.Add(_triggerBhv); } private void CreateEvent(Evt.E_EventType type) { var _mapData = target as Bhv_MapData; if (type == Evt.E_EventType.Enemy) { int _id = _mapData.RequestEventID(); var _event = CreateNewGO(Bhv_MapData.NodeName_Event + "RefreshEvemy_" + _id); var _eventBhv = _event.AddComponent(); _eventBhv.id = _id; _eventBhv.type = type; _event.transform.SetParent(_mapData.transform.Find(Bhv_MapData.NodeName_EventList)); _mapData.eventList.Add(_eventBhv); _event.transform.position = SceneCameraRaycastPosition(); } else if (type == Evt.E_EventType.SceneObject) { int _id = _mapData.RequestEventID(); var _event = CreateNewGO(Bhv_MapData.NodeName_Event + "RefreshSceneObject_" + _id); var _eventBhv = _event.AddComponent(); _eventBhv.id = _id; _eventBhv.type = type; _event.transform.SetParent(_mapData.transform.Find(Bhv_MapData.NodeName_EventList)); _mapData.eventList.Add(_eventBhv); _event.transform.position = SceneCameraRaycastPosition(); } } private void CreateTransferPoint() { var _mapData = target as Bhv_MapData; var _transfer = CreateNewGO(Bhv_MapData.NodeName_Transfer + _mapData.transferList.Count); var _transferBhv = _transfer.AddComponent(); _transfer.transform.SetParent(_mapData.transform.Find(Bhv_MapData.NodeName_TransferList)); _mapData.transferList.Add(_transferBhv); } private void Save() { var _mapData = target as Bhv_MapData; string _defaultPath = EditorPrefs.GetString(LS_KEY_SAVEPATH, System.Environment.CurrentDirectory); string _path = EditorUtility.SaveFilePanel("保存数据", _defaultPath, "map_" + _mapData.id, "ed"); if (string.IsNullOrEmpty(_path)) { return; } using (var _fileStream = File.OpenWrite(_path)) { using (var _binaryWriter = new BinaryWriter(_fileStream)) { _mapData.Save(_binaryWriter); EditorPrefs.SetString(LS_KEY_SAVEPATH, Directory.GetParent(_path).FullName); } } } private void SaveJson() { var _mapData = target as Bhv_MapData; string _defaultPath = EditorPrefs.GetString(LS_KEY_SAVEPATH, System.Environment.CurrentDirectory); string _path = EditorUtility.SaveFilePanel("保存数据", _defaultPath, "map_" + _mapData.id, "json"); if (string.IsNullOrEmpty(_path)) { return; } EditorPrefs.SetString(LS_KEY_SAVEPATH, Path.GetDirectoryName(_path)); File.WriteAllText(_path, _mapData.SaveJson()); } private void LoadJson() { var _defaultPath = EditorPrefs.GetString(LS_KEY_SAVEPATH); if (string.IsNullOrEmpty(_defaultPath)) { _defaultPath = System.Environment.CurrentDirectory; } var _loadPath = EditorUtility.OpenFilePanel("读取Json数据", _defaultPath, "json"); if (string.IsNullOrEmpty(_loadPath)) { return; } var _mapData = target as Bhv_MapData; _mapData.Clear(); var _strJson = File.ReadAllText(_loadPath); var _jsonData = LitJson.JsonMapper.ToObject(_strJson); _mapData.LoadJson(_jsonData); } private void Export() { var _mapData = target as Bhv_MapData; string _defaultPath = EditorPrefs.GetString(LS_KEY_EXPORTPATH, Application.dataPath + "/ResourcesOut/Refdata/Config/"); string _path = EditorUtility.SaveFilePanel("导出数据", _defaultPath, MapData.MapEditorData_Suffix + _mapData.id, "txt"); if (string.IsNullOrEmpty(_path)) { return; } using (var _fileStream = File.OpenWrite(_path)) { using (var _binaryWriter = new BinaryWriter(_fileStream, System.Text.Encoding.UTF8)) { _mapData.Export(_binaryWriter); EditorPrefs.SetString(LS_KEY_EXPORTPATH, Directory.GetParent(_path).FullName); } } } private void Load() { var _mapData = target as Bhv_MapData; string _defaultPath = EditorPrefs.GetString(LS_KEY_SAVEPATH, System.Environment.CurrentDirectory); string _path = EditorUtility.OpenFilePanel("打开数据", _defaultPath, "ed"); if (string.IsNullOrEmpty(_path)) { return; } _mapData.Clear(); using (var _fileStream = File.OpenRead(_path)) { using (var _binaryReader = new BinaryReader(_fileStream, System.Text.Encoding.UTF8)) { _mapData.Load(_binaryReader); EditorPrefs.SetString(LS_KEY_SAVEPATH, Directory.GetParent(_path).FullName); foreach (var _event in _mapData.eventList) { if (_event.id >= _mapData.GetEventSeed()) { _mapData.SetEventID(_event.id + 1); } } foreach (var _trigger in _mapData.triggerList) { if (_trigger.id >= _mapData.GetTriggerSeed()) { _mapData.SetTriggerID(_trigger.id + 1); } } } } } public static Vector3 SceneCameraRaycastPosition() { RaycastHit _hit; Ray _ray = SceneView.lastActiveSceneView.camera.ViewportPointToRay(new Vector3(.5f, .5f, 0)); if (Physics.Raycast(_ray, out _hit, 1000f, LayerUtility.WalkbleMask)) { return _hit.point; } return Vector3.zero; } } }