/// <summary> /// 获取场景输出路径 /// </summary> public static string GetSceneOutputPath(string subPath) { var sceneName = UtilityTools.GetFileName(EditorApplication.currentScene); string path = null; if (string.IsNullOrEmpty(subPath)) { path = string.Format("Assets/Export/Back/Output/{0}", sceneName); UtilityTools.CreateDir(path); } else { path = string.Format("Assets/Export/Back/Output/{0}/{1}", sceneName, subPath); UtilityTools.CreateDir(path); } return(path); }
/// <summary> /// 导出场景 /// </summary> public static bool ExportCurrentScene(bool useSceneFolder, bool compress) { var sceneName = UtilityTools.GetFileName(EditorApplication.currentScene); string pathName; if (useSceneFolder) { pathName = UtilityTools.GenResExportPath(string.Format("scene/{0}", sceneName), sceneName); } else { pathName = UtilityTools.GenResExportPath("scene", sceneName); } if (string.IsNullOrEmpty(pathName)) { return(false); } var options = BuildOptions.None; if (!compress) { options |= BuildOptions.UncompressedAssetBundle; } // 导出 var levels = new string[] { EditorApplication.currentScene }; BuildPipeline.PushAssetDependencies(); string error = BuildPipeline.BuildStreamedSceneAssetBundle(levels, pathName, EditorUserBuildSettings.activeBuildTarget, options); if (!string.IsNullOrEmpty(error)) { EndExportAsset(); Debug.LogErrorFormat("Export Scene \"{0}\" failed! error: {1}", sceneName, error); return(false); } EndExportAsset(); return(true); }
/// ----------------------------------------------------------------------------------------------------------- /// <summary> /// 初始化窗口的布局 /// </summary> /// ----------------------------------------------------------------------------------------------------------- void OnEnable() { if (Application.isPlaying) { return; } string sceneName = UtilityTools.GetFileName(EditorApplication.currentScene); TerrainPatchPath = "Assets/Export/TearrinPatch/" + sceneName; if (!Directory.Exists(TerrainPatchPath)) { Directory.CreateDirectory(TerrainPatchPath); } /// 属性 lable1 = new GUIContent("选择地图"); lable3 = new GUIContent("分割维度"); lable4 = new GUIContent("保存路径"); lable5 = new GUIContent("重置路径"); lable6 = new GUIContent("覆盖数据"); lable7 = new GUIContent("平滑边缘"); lable8 = new GUIContent("拷贝植被"); lable9 = new GUIContent("拷贝细节"); selection = Selection.activeObject as GameObject; if (selection != null) { baseTerrain = selection.GetComponent <Terrain>(); resolutionPerPatch = baseTerrain.terrainData.detailResolutionPerPatch; } if (baseTerrain == null) { Debug.Log("选择的GameOject 没有 Terrain 属性"); return; } }
//--------------------------------------------------------------------------------------- // 开启 //--------------------------------------------------------------------------------------- void OnEnable() { _sceneName = UtilityTools.GetFileName(EditorApplication.currentScene); LoadSettings(); }
//--------------------------------------------------------------------------------------- // OnGUI //--------------------------------------------------------------------------------------- void OnGUI() { // 场景名字 var scenePath = EditorApplication.currentScene; string sceneName = UtilityTools.GetFileName(scenePath); if (_sceneName != sceneName) { _sceneName = sceneName; LoadSettings(); } EditorGUI.BeginChangeCheck(); // 树列表 EditorGUILayout.LabelField("场景树"); for (int i = 0; i < _settings.trees.Count; ++i) { DrawSeparator(1, 1); var tree = _settings.trees[i]; tree.name = EditorGUILayout.TextField("名称", tree.name); tree.splitType = (SceneTreeSplitType)EditorGUILayout.EnumPopup("划分类型", tree.splitType); tree.objType = (SceneTreeObjType)EditorGUILayout.EnumPopup("对象类型", tree.objType); tree.maxDepth = EditorGUILayout.IntField("最大层数", tree.maxDepth); tree.viewDistance = EditorGUILayout.FloatField("可视距离", tree.viewDistance); tree.maxItemBoundsSize = EditorGUILayout.FloatField("最大物体大小", tree.maxItemBoundsSize); } // 导出 GUILayout.FlexibleSpace(); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); _recovertScene = GUILayout.Toggle(_recovertScene, "导出完是否恢复"); _backScene = GUILayout.Toggle(_backScene, "备份场景"); _compressScene = GUILayout.Toggle(_compressScene, "压缩场景"); _compressRes = GUILayout.Toggle(_compressRes, "压缩资源"); GUILayout.EndHorizontal(); GUILayout.Space(20); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("检查设置", GUILayout.Width(100))) { int settingsObjTypeFlag = 0; SceneTree.CheckSettings(_settings.trees, out settingsObjTypeFlag); } else if (GUILayout.Button("导出资源", GUILayout.Width(100))) { BuildScene(_backScene, true, _compressScene, _compressRes); } else { GUILayout.EndHorizontal(); GUILayout.Space(10); if (EditorGUI.EndChangeCheck()) { SaveSettings(); } } }
/// <summary> /// 生成场景 /// </summary> void BuildScene(bool exportScene, bool exportRes, bool compressScene, bool compressRes) { // 先保存场景 EditorApplication.SaveScene(); // 场景名字 var scenePath = EditorApplication.currentScene; string sceneName = UtilityTools.GetFileName(scenePath); // 导出目录 var exportPath = UtilityTools.GenResExportPath(string.Format("scene/{0}", sceneName), sceneName); var exportDir = Path.GetDirectoryName(exportPath); // 删除目录 if (exportRes && exportScene) { Directory.Delete(exportDir, true); } // 创建目录 if (!Directory.Exists(exportDir)) { Directory.CreateDirectory(exportDir); } /// 开始处理数据 try { do { AssetsBackuper.inst.Clear(); if (exportScene) { var outputDir = EditorUtil.GetSceneOutputPath(null); AssetDatabase.DeleteAsset(outputDir); var outputPath = EditorUtil.GetSceneOutputPath(string.Format("{0}.unity", sceneName)); EditorApplication.SaveScene(outputPath); } // 树结构 var meshColliders = new List <MeshCollider>(); var trees = SceneTree.Build(_settings.trees, meshColliders); if (null == trees) { break; } SaveSettings(); SceneTree.Export(trees, meshColliders, exportRes, compressRes); // 准备导出 EditorApplication.SaveScene(); AssetDatabase.SaveAssets(); if (exportScene) { ResExportUtil.ExportCurrentScene(true, compressScene); } }while(false); } catch (Exception e) { Debug.LogException(e); AssetsBackuper.inst.Recover(); AssetDatabase.SaveAssets(); } finally { // 还原修改过的资源和场景 if (_recovertScene) { AssetsBackuper.inst.Recover(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); EditorApplication.OpenScene(scenePath); Resources.UnloadUnusedAssets(); } } }
/// ----------------------------------------------------------------------------------------------------------- /// <summary> /// 草自适应地形 /// </summary> /// ----------------------------------------------------------------------------------------------------------- public void TerrainMergeMaker( ) { GameObject[] Objects = GameObject.FindGameObjectsWithTag("EditorTerrain"); if (Objects == null || Objects.Length <= 0) { return; } // 清空历史记录 string sceneName = UtilityTools.GetFileName(EditorApplication.currentScene); string mergeFile = "Assets/TerrainPatch/" + sceneName + "/" + sceneName + "Merge.asset"; File.Delete(mergeFile); InitTerrainPatchs(); GameObject terrainGameObject = null; Terrain terrain = null; TerrainData data = null; // 创建地图文件 EditorUtility.DisplayProgressBar("progress", " progress terrain", 0.2f); AssetDatabase.CreateAsset(new TerrainData(), mergeFile); TerrainData terdata = AssetDatabase.LoadAssetAtPath(mergeFile, typeof(TerrainData)) as TerrainData; terrainGameObject = Terrain.CreateTerrainGameObject(terdata); terrainGameObject.name = sceneName + "Merge"; terrain = terrainGameObject.GetComponent <Terrain>(); data = terrain.terrainData; data.heightmapResolution = _newHMapResolution + 1; data.alphamapResolution = _newAlphamapResolution; data.baseMapResolution = _newBaseMapResolution; data.SetDetailResolution(_newDetlResolution, _newresolutionPerPatch); data.size = new Vector3(_newTerrainLeght, _newTerrainHeight, _newTerrainWidth); // 拷贝地图数据到新的地图中 data.treePrototypes = _listTreeProto.ToArray(); data.detailPrototypes = _listDetaill.ToArray(); data.splatPrototypes = _listSplatPrototype.ToArray(); EditorUtility.DisplayProgressBar("progress", " progress terrain", 0.3f); Terrain ter = Objects[0].GetComponent <Terrain>(); if (ter == null) { return; } // 处理地图细节转换 int nTerrainPatchSize = (int)(ter.terrainData.size.x); int nWidth = _TerrainPatchs.GetLength(0); int nLenght = _TerrainPatchs.GetLength(1); ProgessScale = ProgessScale / (nWidth * nLenght); for (int x = 0; x < nWidth; x++) { for (int z = 0; z < nLenght; z++) { if (_TerrainPatchs[x, z].ter != null) { ProcessTerrainHeights(_TerrainPatchs[x, z].ter, terrain); ProcessTerrainDetail(_TerrainPatchs[x, z].ter, terrain); ProcessTerrainSplats(_TerrainPatchs[x, z].ter, terrain); ProcessTerrainVegetation(_TerrainPatchs[x, z].ter, terrain); } _progress += ProgessScale; EditorUtility.DisplayProgressBar("progress", " progress terrain", _progress); } } EditorUtility.ClearProgressBar(); }
/// ----------------------------------------------------------------------------------------------------------- /// <summary> /// 绘制窗口布局 /// </summary> /// ----------------------------------------------------------------------------------------------------------- void OnGUI() { if (!Application.isPlaying) { GUILayout.Label("配置选项", EditorStyles.boldLabel); EditorGUILayout.Space(); baseTerrain = (Terrain)EditorGUILayout.ObjectField(lable1, baseTerrain, typeof(Terrain), false); EditorGUILayout.Space(); excusuibType = (SlicingType)EditorGUILayout.EnumPopup(lable3, excusuibType); EditorGUILayout.Space(); TerrainPatchPath = EditorGUILayout.TagField(lable4, TerrainPatchPath); EditorGUILayout.Space(); if (GUILayout.Button(lable5)) { string sceneName = UtilityTools.GetFileName(EditorApplication.currentScene); TerrainPatchPath = "Assets/TerrainPatch/" + sceneName + "/TearrinData"; } EditorGUILayout.Space(); IsOverWrite = EditorGUILayout.Toggle(lable6, IsOverWrite); EditorGUILayout.Space(); IsSmoothEdge = EditorGUILayout.Toggle(lable7, IsSmoothEdge); EditorGUILayout.Space(); IsCopyNegtion = EditorGUILayout.Toggle(lable8, IsCopyNegtion); EditorGUILayout.Space(); IsCopyDetail = EditorGUILayout.Toggle(lable9, IsCopyDetail); /// 开始分割地形 if (GUILayout.Button("开始分割地形")) { if (baseTerrain == null) { this.ShowNotification(new GUIContent("base terrain is null ")); return; } ClearHistoryCache(); /// 计算一些参数 baseData = baseTerrain.terrainData; int nSize = (int)excusuibType; _newTerrainWide = nSize; _newTerrainHeight = nSize; _newHeightMapResolution = (baseData.heightmapResolution - 1) / nSize + 1; _newAlphaMapResolution = baseData.alphamapResolution / nSize; _newBaseMapResolution = baseData.baseMapResolution / nSize; _newDetailResolution = baseData.detailResolution / nSize; if (CheckConfigError()) { SlicingTerrainData(); } if (IsSmoothEdge) { SmoothPatchEdges(); } SetNeighbors(); this.Close(); } } }