/*一些其他操作*/ void OtherOperator(HLODGenerate hlodGenerate) { //设置延时卸载时间 /* * float value = EditorGUILayout.FloatField("DelayUnLoadTime", hlodGenerate.m_DelayUnLoadTime); * if(value != hlodGenerate.m_DelayUnLoadTime) * { * hlodGenerate.m_DelayUnLoadTime = value; * ChildTreeRoot [] roots = hlodGenerate.GetComponentsInChildren<ChildTreeRoot>(); * foreach(var root in roots) * { * root.m_DelayUnLoadTime = value; * } * }*/ //距离缓冲设置,全局 /* * if (hlodGenerate.m_CacheDistance != HLODEditor.GI_CacheDistance) * { * hlodGenerate.m_CacheDistance = HLODEditor.GI_CacheDistance; * EditorUtility.SetDirty(hlodGenerate); * }*/ }
public override void OnInspectorGUI() { base.OnInspectorGUI(); HLODGenerate hlodGenerate = (HLODGenerate)target; OtherOperator(hlodGenerate); string nullSearch = null; GUILayout.BeginVertical(); DrawHeader("Mesh", ref nullSearch, 0, true); MeshOperator(hlodGenerate); GUILayout.Space(10); DrawHeader("Texture", ref nullSearch, 0, true); MatsAndTexsOperator(hlodGenerate); GUILayout.Space(10); DrawHeader("Generate", ref nullSearch, 0, true); GUILayout.BeginHorizontal(); GenerateHLODS(hlodGenerate); GUILayout.EndHorizontal(); GUILayout.Space(10); DrawHeader("Streaming", ref nullSearch, 0, true); DrawHeader("Streaming导出的预制体以及合并前的预制体需要添加到AddressablesAssets里才能正常使用", ref nullSearch, 0, true); GUILayout.BeginHorizontal(); GenerateStreamingLoad(hlodGenerate); GUILayout.EndHorizontal(); GUILayout.EndVertical(); }
//删除导出的流式资源 public static void DeleteExportStreamingAsset(this HLODGenerate hlodGenerate) { #if UNITY_EDITOR if (hlodGenerate.m_StreamingAssetPath != "") { AssetDatabase.DeleteAsset(hlodGenerate.m_StreamingAssetPath + "\\" + HLODGenerateEditor.s_StreamingDirectory); } #endif }
public static LODVolume Create(HLODGenerate hlodGenerate) { int volumeCount = hlodGenerate.m_LODVolumeCount++; GameObject go = new GameObject(k_DefaultName + volumeCount, typeof(LODVolume)); LODVolume volume = go.GetComponent <LODVolume>(); volume.m_CurrHLODGenerate = hlodGenerate ? hlodGenerate : volume.m_CurrHLODGenerate; return(volume); }
public void ClearTextureAtlasList(HLODGenerate key) { List <TextureAtlasData> atlasesData = null; if (m_AllAtlases.TryGetValue(key, out atlasesData)) { atlasesData.Clear(); } }
//删除导出的FBX或Mesh资源 public static void DeleteExportMesh(this HLODGenerate hlodGenerate) { #if UNITY_EDITOR if (hlodGenerate.m_IsExportMesh) { AssetDatabase.DeleteAsset(hlodGenerate.m_MeshAssetPath + "\\" + ExportHLODsByMesh.s_DirectoryName); } #endif }
//删除导出的贴图材质 public static void DeleteExportMatTex(this HLODGenerate hlodGenerate) { #if UNITY_EDITOR if (hlodGenerate.m_IsExportMatTex) { AssetDatabase.DeleteAsset(hlodGenerate.m_TextureAssetPath + "\\" + TextureAtlasModule.s_TexDirectoryName); AssetDatabase.DeleteAsset(hlodGenerate.m_MaterialAssetPath + "\\" + TextureAtlasModule.s_MatDirectoryName); } #endif }
/*删除*/ void DeleteHLODs(HLODGenerate hlodGenerate) { DestroyImmediate(hlodGenerate.m_RootLODVolume); DestroyImmediate(hlodGenerate.m_HLODS); hlodGenerate.DeleteExportMesh(); hlodGenerate.DeleteExportMatTex(); hlodGenerate.DeleteExportStreamingAsset(); TextureAtlasModule.instance.ClearTextureAtlasList(hlodGenerate); hlodGenerate.m_IsGenerating = false; hlodGenerate.Init(); }
/*贴图、材质操作*/ void MatsAndTexsOperator(HLODGenerate hlodGenerate) { GUILayout.BeginVertical(); do { GUILayout.BeginHorizontal(); GUILayout.Label("Textures路径:"); GUILayout.Label(hlodGenerate.m_TextureAssetPath + "\\" + TextureAtlasModule.s_TexDirectoryName); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Materials路径:"); GUILayout.Label(hlodGenerate.m_MaterialAssetPath + "\\" + TextureAtlasModule.s_MatDirectoryName); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); if (hlodGenerate.m_IsExportMatTex) { EditorGUILayout.HelpBox("贴图、材质已导出", MessageType.Info); break; } GUILayout.BeginHorizontal(); if (GUILayout.Button("贴图路径选择")) { string path = EditorUtility.OpenFolderPanel("Save HLODsTextures to....", Application.dataPath, ""); path = path.Replace(Application.dataPath, "Assets"); path = path.Replace("/", "\\"); hlodGenerate.m_TextureAssetPath = path; } if (GUILayout.Button("材质球路径选择")) { string path = EditorUtility.OpenFolderPanel("Save HLODsMaterial to....", Application.dataPath, ""); path = path.Replace(Application.dataPath, "Assets"); path = path.Replace("/", "\\"); hlodGenerate.m_MaterialAssetPath = path; } if (hlodGenerate.m_HLODS != null && GUILayout.Button("导出")) { hlodGenerate.m_IsExportMatTex = true; UpdataCombineMatsAndTexs(hlodGenerate); //ExportTextures(hlodGenerate); } GUILayout.EndHorizontal(); } while (false); GUILayout.EndVertical(); }
//从流式资源中回退 public static void ComeBackInMemory(this HLODGenerate hlodGenerate, HLODGenerateEditor editor) { //还原HLOD hlodGenerate.ComeBackHLODAsset(editor); //还远原始资源 hlodGenerate.ComeBackOriginalAsset(); //删除流式资源 if (editor.m_DeleteStreamingAsset) { hlodGenerate.DeleteExportStreamingAsset(); } }
void GetTextureAtlasList(HLODGenerate hg, out List <TextureAtlasData> atlasesData) { HLODGenerate hlodGenerate = hg; HLODGenerate key = hlodGenerate ? hlodGenerate : s_CommonKey; if (!m_AllAtlases.TryGetValue(key, out atlasesData)) { atlasesData = new List <TextureAtlasData>(); m_AllAtlases.Add(key, atlasesData); return; } // Clear out any atlases that were removed atlasesData.RemoveAll(a => a.m_Atlases == null); }
/*生成SceneLOD接口,指定hlodGenerate*/ public void GenerateSceneLODByHLODGenerate(HLODGenerate hlodGenerate, Action <GameObject, GameObject> endCall = null) { m_CurrHLODGenerate = hlodGenerate; #if UNITY_EDITOR if (hlodGenerate.m_RootLODVolume) { m_RootVolume = hlodGenerate.m_RootLODVolume.GetComponent <LODVolume>(); } else { m_RootVolume = null; } m_CreateRootVolumeForScene = SceneManager.GetActiveScene().name; MonoBehaviourHelper.StartCoroutine(GenerateHLOD(hlodGenerate.m_Targets, endCall)); #endif }
//还原HLOD public static void ComeBackHLODAsset(this HLODGenerate hlodGenerate, HLODGenerateEditor editor) { #if UNITY_EDITOR if (hlodGenerate.m_RootLODVolume == null) { return; } #endif Queue <LODVolume> queue = new Queue <LODVolume>(); #if UNITY_EDITOR queue.Enqueue(hlodGenerate.m_RootLODVolume.GetComponent <LODVolume>()); #endif while (queue.Count > 0) { LODVolume lodVolume = queue.Dequeue(); foreach (var child in lodVolume.childVolumes) { queue.Enqueue(child); } if (lodVolume.combined == null) { continue; } GameObject obj = AssetDatabase.LoadAssetAtPath <GameObject>(lodVolume.combined._assetPath); if (obj) { #if UNITY_EDITOR obj = PrefabUtility.InstantiatePrefab(obj, hlodGenerate.m_HLODS.transform) as GameObject; #endif obj.transform.SetPositionAndRotation(lodVolume.combined.Pose.position, lodVolume.combined.Pose.rotation); obj.transform.localScale = lodVolume.combined.Pose.scale; obj.GetComponent <MeshRenderer>().enabled = false; lodVolume.combined._hlodRoot = obj; lodVolume.combined._lodGroup = obj.GetComponent <LODGroup>(); if (editor.m_DeleteStreamingAsset) { PrefabUtility.UnpackPrefabInstance(obj, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction); } } } }
//还远原始资源 public static void ComeBackOriginalAsset(this HLODGenerate hlodGenerate) { #if UNITY_EDITOR LODVolume root = hlodGenerate.m_RootLODVolume.GetComponent <LODVolume>(); foreach (var lodGroup in root.lodGroups) { GameObject obj = AssetDatabase.LoadAssetAtPath <GameObject>(lodGroup._assetPath); if (obj) { obj = PrefabUtility.InstantiatePrefab(obj, hlodGenerate.m_HLODS.transform) as GameObject; obj.transform.parent = lodGroup._hlodRoot.transform;//生成流式资源后_hlodRoot引用的是父节点 obj.transform.SetPositionAndRotation(lodGroup.Pose.position, lodGroup.Pose.rotation); obj.transform.localScale = lodGroup.Pose.scale; lodGroup._hlodRoot = obj; lodGroup._lodGroup = obj.GetComponent <LODGroup>(); lodGroup.Enabled = true; } } #endif }
/*网格操作*/ void MeshOperator(HLODGenerate hlodGenerate) { GUILayout.BeginVertical(); do { GUILayout.BeginHorizontal(); GUILayout.Label("Mesh路径:"); GUILayout.Label(hlodGenerate.m_MeshAssetPath + "\\" + ExportHLODsByMesh.s_DirectoryName); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); if (hlodGenerate.m_IsExportMesh) { EditorGUILayout.HelpBox("网格已导出", MessageType.Info); break; } GUILayout.BeginHorizontal(); if (GUILayout.Button("路径选择")) { string path = EditorUtility.OpenFolderPanel("Save HLODsMesh to....", Application.dataPath, ""); path = path.Replace(Application.dataPath, "Assets"); path = path.Replace("/", "\\"); hlodGenerate.m_MeshAssetPath = path; } if (hlodGenerate.m_HLODS != null && GUILayout.Button("导出")) { hlodGenerate.m_IsExportMesh = true; UpdataCombineMesh(hlodGenerate); //ExportMesh(hlodGenerate); } GUILayout.EndHorizontal(); } while (false); GUILayout.EndVertical(); }
/*更新流式资源*/ void UpdataStreamingAsset(HLODGenerate hlodGenerate) { string savePath = Path.Combine(hlodGenerate.m_StreamingAssetPath, s_StreamingDirectory); if (!Directory.Exists(savePath)) { Directory.CreateDirectory(savePath); } LODVolume rootLODVolume = hlodGenerate.m_RootLODVolume.GetComponent <LODVolume>(); Queue <LODVolume> queue = new Queue <LODVolume>(); queue.Enqueue(rootLODVolume); AssetDatabase.StartAssetEditing(); while (queue.Count > 0) { LODVolume lodVolume = queue.Dequeue(); foreach (var child in lodVolume.childVolumes) { queue.Enqueue(child); } if (lodVolume.combined == null) { continue; } //导出资源 GeneratePrefab(lodVolume, savePath); } AssetDatabase.StopAssetEditing(); GenrateFineModelRef(hlodGenerate.m_RootLODVolume.GetComponent <LODVolume>()); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }
/*更新合批网格*/ void UpdataCombineMesh(HLODGenerate hlodGenerate) { if (!hlodGenerate.m_IsExportMesh) { return; } if (hlodGenerate.m_MeshAssetPath == "") { EditorUtility.DisplayDialog("警告", "没有选择mesh路径,请先选择路径", "是"); hlodGenerate.m_IsExportMesh = false; return; } Queue <LODVolume> queue = new Queue <LODVolume>(); queue.Enqueue(hlodGenerate.m_RootLODVolume.GetComponent <LODVolume>()); //AssetDatabase.StartAssetEditing(); while (queue.Count > 0) { LODVolume lodVolume = queue.Dequeue(); if (lodVolume.combined != null && lodVolume.combined._hlodRoot != null) { string path = AssetDatabase.GetAssetPath(lodVolume.combined._hlodRoot.GetComponent <MeshFilter>().sharedMesh); if (lodVolume.lodGroups.Count < 1)//删除多出来的资源 { if (path == "") { path = Path.Combine(hlodGenerate.m_MeshAssetPath, ExportHLODsByMesh.s_DirectoryName, lodVolume.combined._hlodRoot.name); path = Path.ChangeExtension(path, "asset"); } DestroyImmediate(lodVolume.GetComponent <LODGroup>()); DestroyImmediate(lodVolume.combined._hlodRoot); lodVolume.combined._hlodRoot = null; if (path != "") { AssetDatabase.DeleteAsset(path); } } else if (path == "")//更新资源 { //ExportHLODsByMesh.PersistHLODs(lodVolume.hlodRoot.transform, hlodGenerate.m_MeshAssetPath); ExportHLODsByMesh.PersistHLODOfFbx(lodVolume.combined._hlodRoot.transform, hlodGenerate.m_MeshAssetPath); if (!hlodGenerate.StreamUpdate.Contains(lodVolume)) { hlodGenerate.StreamUpdate.Add(lodVolume); } } EditorUtility.SetDirty(lodVolume); } foreach (LODVolume lv in lodVolume.childVolumes) { queue.Enqueue(lv); } } //AssetDatabase.StopAssetEditing(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }
public IEnumerator GetTextureAtlas(HLODGenerate hg, LODVolume lodVolume, Texture2D[] textures, Texture2D[] normals, Action <TextureAtlasData> callback) { TextureAtlasData atlasData = null; List <TextureAtlasData> atlasesData = null; GetTextureAtlasList(hg, out atlasesData); yield return(null); foreach (var a in atlasesData) { if (a.m_State == TextureAtlasData.State.Delete) { continue; } //检查是否为所在树的贴图集 if (!CheckInCurrLittleOctree(lodVolume, a)) { continue; } //是否重新生成 if (IsReGenerate(lodVolume, textures, a.m_Atlases)) { a.m_State = TextureAtlasData.State.Delete; break; } // At a minimum the atlas should have all of the textures requested, but can be a superset if (!textures.Except(a.m_Atlases.textures).Any()) { atlasData = a; break; } yield return(null); } //m_Atlases.Remove(deleteAtlas); if (atlasData == null)//没有找到图集就创建一个 { atlasData = new TextureAtlasData(null, TextureAtlasData.State.Add); atlasData.m_Material = new Material(Shader.Find("Standard")); /*先序遍历,所有根节点就是第一个创建的对象,子节点会找到这个图集而不会继续创建*/ atlasData.m_Root = lodVolume.gameObject; } if (!atlasData.m_Atlases) { atlasData.m_Atlases = ScriptableObject.CreateInstance <TextureAtlas>(); TextureReadableSetting(textures); //TextureReadableSetting(normals); CombineTexture(textures, atlasData.m_Atlases, false, callback); //CombineTexture(normals, atlasData.m_Atlases, true, callback); atlasData.m_Material.mainTexture = atlasData.m_Atlases.textureAtlas; //material.SetTexture("_NormalMap", atlasData.m_Atlases.textureAtlas_N); atlasesData.Add(atlasData); yield return(null); } if (callback != null) { callback(atlasData); } }
public IEnumerator Batch(HLODGenerate hg, LODVolume lodVolume) { GameObject go = lodVolume.combined._hlodRoot; var renderers = go.GetComponentsInChildren <Renderer>(); var materials = new HashSet <Material>(renderers.SelectMany(r => r.sharedMaterials)); List <Texture2D> textures = new List <Texture2D>(); List <Texture2D> normals = new List <Texture2D>(); textures = new HashSet <Texture2D>(materials.Select(m => { if (m) { return(m.mainTexture as Texture2D); } return(null); }).Where(t => t != null)).ToList(); textures.Add(whiteTexture); /* * foreach(var t2d in textures) * { * foreach(var rd in renderers) * { * if(rd.sharedMaterial.mainTexture == t2d) * { * Texture2D t = rd.sharedMaterial.GetTexture("_BumpMap") as Texture2D; * if (t == null) * { * var texture = new Texture2D(rd.sharedMaterial.mainTexture.width, rd.sharedMaterial.mainTexture.height, TextureFormat.RGB24, false, PlayerSettings.colorSpace == ColorSpace.Linear); * * t = texture; * //texture.Apply(); * } * else if(t.width != rd.sharedMaterial.mainTexture.width || t.height != rd.sharedMaterial.mainTexture.height) * { * int width = rd.sharedMaterial.mainTexture.width; * int height = rd.sharedMaterial.mainTexture.height; * var texture = new Texture2D(rd.sharedMaterial.mainTexture.width, rd.sharedMaterial.mainTexture.height, t.format, false, PlayerSettings.colorSpace == ColorSpace.Linear); * * * for(int i = 0; i < height; i++) * { * for(int j = 0; j <width; j++) * { * //EditorUtility.DisplayProgressBar("fsdfasd", (height * width).ToString(), (float)(i * j) / (height * width)); * // Color newColor = t.GetPixelBilinear(j / width, i / height); * texture.SetPixel(j, i, Color.white); * } * } * //EditorUtility.ClearProgressBar(); * texture.Apply(); * t = texture; * } * normals.Add(t); * break; * } * } * } * normals.Add(whiteTexture); */ TextureAtlasData atlasData = null; yield return(TextureAtlasModule.instance.GetTextureAtlas(hg, lodVolume, textures.ToArray(), normals.ToArray(), a => atlasData = a)); var mainAtlasLookup = new Dictionary <Texture2D, Rect>(); //var normalAtlasLookup = new Dictionary<Texture2D, Rect>(); var atlasTextures = atlasData.m_Atlases.textures; for (int i = 0; i < atlasTextures.Length; i++) { mainAtlasLookup[atlasTextures[i]] = atlasData.m_Atlases.uvs[i]; } MeshFilter[] meshFilters = go.GetComponentsInChildren <MeshFilter>(); var combine = new List <CombineInstance>(); for (int i = 0; i < meshFilters.Length; i++) { var mf = meshFilters[i]; var sharedMesh = mf.sharedMesh; if (!sharedMesh) { continue; } if (!sharedMesh.isReadable) { var assetPath = AssetDatabase.GetAssetPath(sharedMesh); if (!string.IsNullOrEmpty(assetPath)) { var importer = AssetImporter.GetAtPath(assetPath) as ModelImporter; if (importer) { importer.isReadable = true; importer.SaveAndReimport(); } } } var ci = new CombineInstance(); var mesh = UnityEngine.Object.Instantiate(sharedMesh); var mr = mf.GetComponent <MeshRenderer>(); var sharedMaterials = mr.sharedMaterials; var uv = mesh.uv; if (uv == null) { uv = mesh.uv2; } var colors = mesh.colors; if (colors == null || colors.Length == 0) { colors = new Color[uv.Length]; } var updated = new bool[uv.Length]; var triangles = new List <int>(); // Some meshes have submeshes that either aren't expected to render or are missing a material, so go ahead and skip var subMeshCount = Mathf.Min(mesh.subMeshCount, sharedMaterials.Length); for (int j = 0; j < subMeshCount; j++) { var sharedMaterial = sharedMaterials[Mathf.Min(j, sharedMaterials.Length - 1)]; var mainTexture = whiteTexture; var materialColor = Color.white; if (sharedMaterial) { var texture = sharedMaterial.mainTexture as Texture2D; //sharedMaterial.texture if (texture) { mainTexture = texture; } if (sharedMaterial.HasProperty("_Color")) { materialColor = sharedMaterial.color; } } if (mesh.GetTopology(j) != MeshTopology.Triangles) { Debug.LogWarning("Mesh must have triangles", mf); continue; } triangles.Clear(); mesh.GetTriangles(triangles, j); var uvOffset = mainAtlasLookup[mainTexture]; foreach (var t in triangles) { if (!updated[t]) { var uvCoord = uv[t]; if (mainTexture == whiteTexture) { // Sample at center of white texture to avoid sampling edge colors incorrectly uvCoord.x = 0.5f; uvCoord.y = 0.5f; } while (uvCoord.x < 0) { uvCoord.x += 1; } while (uvCoord.y < 0) { uvCoord.y += 1; } while (uvCoord.x > 1) { uvCoord.x -= 1; } while (uvCoord.y > 1) { uvCoord.y -= 1; } uvCoord.x = Mathf.Lerp(uvOffset.xMin, uvOffset.xMax, uvCoord.x); uvCoord.y = Mathf.Lerp(uvOffset.yMin, uvOffset.yMax, uvCoord.y); uv[t] = uvCoord; if (mainTexture == whiteTexture) { colors[t] = materialColor; } else { colors[t] = Color.white; } updated[t] = true; } } yield return(null); } mesh.uv = uv; mesh.uv2 = null; mesh.colors = colors; ci.mesh = mesh; ci.transform = mf.transform.localToWorldMatrix; combine.Add(ci); mf.gameObject.SetActive(false); yield return(null); } var combinedMesh = new Mesh(); #if UNITY_2017_3_OR_NEWER combinedMesh.indexFormat = IndexFormat.UInt32; #endif combinedMesh.CombineMeshes(combine.ToArray(), true, true); combinedMesh.RecalculateBounds(); var meshFilter = go.AddComponent <MeshFilter>(); meshFilter.sharedMesh = combinedMesh; for (int i = 0; i < meshFilters.Length; i++) { UnityEngine.Object.DestroyImmediate(meshFilters[i].gameObject); } var meshRenderer = go.AddComponent <MeshRenderer>(); meshRenderer.sharedMaterial = atlasData.m_Material; atlasData.m_MeshRenderers.Add(meshRenderer); }
/*生成、更新操作*/ void GenerateHLODS(HLODGenerate hlodGenerate) { if (hlodGenerate == null || hlodGenerate.m_Targets == null || hlodGenerate.m_Targets.Length < 1) { return; } if (hlodGenerate.m_IsGenerating) { EditorGUILayout.HelpBox("正在工作中。。。", MessageType.Warning); return; } if (hlodGenerate.m_IsStreaming) { EditorGUILayout.HelpBox("请先回退后再操作", MessageType.Warning); return; } if (!hlodGenerate.m_IsGenerate) { if (GUILayout.Button("生成HLODS")) { if (!hlodGenerate.m_GenerateAsset) { if (!EditorUtility.DisplayDialog("提示", "建议生成后就导出贴图,贴图的索引缓存在内存中,只要代码重新编译缓存就会被清除!!", "好了,我知道了")) { return; } } MonoBehaviourHelper.instance.DestroySurrogate(); hlodGenerate.m_IsGenerating = true; SceneLOD.instance.GenerateSceneLODByHLODGenerate(hlodGenerate, (GameObject bvhRoot, GameObject hlodsRoot) => { if (bvhRoot != null && hlodsRoot != null) { //将生成的hlods与bvh管理起来 bvhRoot.transform.parent = hlodGenerate.transform; hlodsRoot.transform.parent = hlodGenerate.transform; hlodGenerate.m_RootLODVolume = bvhRoot; hlodGenerate.m_HLODS = hlodsRoot; hlodGenerate.m_IsGenerate = true; if (hlodGenerate.m_GenerateAsset) { hlodGenerate.m_IsExportMesh = true; hlodGenerate.m_IsExportMatTex = true; UpdataCombineMesh(hlodGenerate); UpdataCombineMatsAndTexs(hlodGenerate); } EditorUtility.SetDirty(hlodGenerate); EditorUtility.SetDirty(hlodGenerate.gameObject); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } hlodGenerate.m_IsGenerating = false; }); } hlodGenerate.m_GenerateAsset = GUILayout.Toggle(hlodGenerate.m_GenerateAsset, "同时导出资源"); /*查看是否已经选择了mesh和texture导出路径*/ if (hlodGenerate.m_GenerateAsset) { if (hlodGenerate.m_MeshAssetPath == "") { EditorUtility.DisplayDialog("警告", "没有选择mesh路径,请先选择路径", "是"); hlodGenerate.m_GenerateAsset = false; return; } if (hlodGenerate.m_TextureAssetPath == "") { EditorUtility.DisplayDialog("警告", "没有选择textures路径,请先选择路径", "是"); hlodGenerate.m_GenerateAsset = false; return; } } } else { if (GUILayout.Button("更新")) { MonoBehaviourHelper.instance.DestroySurrogate(); hlodGenerate.m_IsGenerating = true; SceneLOD.instance.OnUpdataBVHByHLODGenerate(hlodGenerate, (GameObject bvhRoot, GameObject hlodsRoot) => { if (bvhRoot != null && hlodsRoot != null) { UpdataCombineMesh(hlodGenerate); UpdataCombineMatsAndTexs(hlodGenerate); } hlodGenerate.m_IsGenerating = false; }); } if (GUILayout.Button("删除HLOD(同时删除资源)")) { if (EditorUtility.DisplayDialog("警告", "本次操作会伴随删除对应生成的贴图和mesh目录", "删除", "我再想想")) { DeleteHLODs(hlodGenerate); } } } }
/*流式操作*/ void GenerateStreamingLoad(HLODGenerate hlodGenerate) { if (hlodGenerate.m_RootLODVolume) { HLODCull hlodCull = hlodGenerate.m_RootLODVolume.GetComponent <HLODCull>(); if (hlodCull) { hlodCull.m_Stream = hlodGenerate.m_IsStreaming; } } if (!hlodGenerate.m_IsExportMatTex || !hlodGenerate.m_IsExportMesh) { return; } GUILayout.BeginVertical(); do { GUILayout.BeginHorizontal(); GUILayout.Label("Streming路径:"); GUILayout.Label(hlodGenerate.m_StreamingAssetPath + "\\" + s_StreamingDirectory); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); if (hlodGenerate.m_IsStreaming && hlodGenerate.StreamUpdate.Count > 0 && GUILayout.Button("更新")) { string savePath = Path.Combine(hlodGenerate.m_StreamingAssetPath, s_StreamingDirectory); foreach (var lv in hlodGenerate.StreamUpdate) { GeneratePrefab(lv, savePath); } hlodGenerate.StreamUpdate.Clear(); GenrateFineModelRef(hlodGenerate.m_RootLODVolume.GetComponent <LODVolume>()); } if (hlodGenerate.m_IsStreaming) { GUILayout.BeginHorizontal(); m_DeleteStreamingAsset = GUILayout.Toggle(m_DeleteStreamingAsset, "同时删除流式资源"); if (GUILayout.Button("退回")) { hlodGenerate.ComeBackInMemory(this); hlodGenerate.m_IsStreaming = false; EditorUtility.SetDirty(hlodGenerate.gameObject); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } GUILayout.EndHorizontal(); EditorGUILayout.HelpBox("Streaming已生成", MessageType.Info); break; } GUILayout.BeginHorizontal(); if (GUILayout.Button("路径选择")) { string path = EditorUtility.OpenFolderPanel("Save HLODsStreaming to....", Application.dataPath, ""); path = path.Replace(Application.dataPath, "Assets"); path = path.Replace("/", "\\"); hlodGenerate.m_StreamingAssetPath = path; } if (hlodGenerate.m_StreamingAssetPath != "" && GUILayout.Button("导出")) { hlodGenerate.m_IsStreaming = true; UpdataStreamingAsset(hlodGenerate); hlodGenerate.StreamUpdate.Clear(); EditorUtility.SetDirty(hlodGenerate.gameObject); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } GUILayout.EndHorizontal(); } while (false); GUILayout.EndVertical(); }
/*更新BVH*/ public void OnUpdataBVHByHLODGenerate(HLODGenerate hlodGenerate, Action <GameObject, GameObject> endCall = null) { GenerateSceneLODByHLODGenerate(hlodGenerate, endCall); }
/*更新合批贴图、材质球*/ void UpdataCombineMatsAndTexs(HLODGenerate hlodGenerate) { Dictionary <HLODGenerate, List <TextureAtlasData> > m_AllAtlases = TextureAtlasModule.instance.AllAtlases; List <TextureAtlasData> data = null; if (m_AllAtlases.TryGetValue(hlodGenerate, out data)) { List <TextureAtlasData> remove = m_RemovedTextureAtlasData; List <TextureAtlasData> add = m_AddedTextureAtlasData; remove.Clear(); add.Clear(); //标记delete的就删除并删除资源,标记add就添加或更新 for (int i = 0; i < data.Count; i++) { TextureAtlasData taData = data[i]; switch (taData.m_State) { case TextureAtlasData.State.Delete: remove.Add(taData); break; case TextureAtlasData.State.Add: taData.m_MeshRenderers.RemoveAll(r => r == null); if (taData.m_MeshRenderers.Count > 0) { add.Add(taData); } else { taData.m_State = TextureAtlasData.State.Delete; remove.Add(taData); } //删除空renderer break; } } data.RemoveAll(r => r.m_State == TextureAtlasData.State.Delete); if (hlodGenerate.m_IsExportMatTex) { if (hlodGenerate.m_TextureAssetPath == "") { EditorUtility.DisplayDialog("警告", "没有选择textures路径,请先选择路径", "是"); hlodGenerate.m_IsExportMatTex = false; return; } if (hlodGenerate.m_MaterialAssetPath == "") { EditorUtility.DisplayDialog("警告", "没有选择materials路径,请先选择路径", "是"); hlodGenerate.m_IsExportMatTex = false; return; } int progressCount = 1; foreach (TextureAtlasData r in remove) { EditorUtility.DisplayProgressBar("删除图集", r.m_Root.name, (float)progressCount++ / remove.Count); TextureAtlasModule.DeleteOnlyOneTextureAtlasData(r); } progressCount = 1; foreach (TextureAtlasData a in add) { EditorUtility.DisplayProgressBar("保存图集", a.m_Root.name, (float)progressCount++ / add.Count); TextureAtlasModule.ExportOnlyOneTextureAtlasData(a, hlodGenerate.m_TextureAssetPath, hlodGenerate.m_MaterialAssetPath, a.m_MeshRenderers[0].name); foreach (MeshRenderer mr in a.m_MeshRenderers) { mr.sharedMaterial = a.m_Material; } a.m_State = TextureAtlasData.State.None; } } remove.Clear(); add.Clear(); EditorUtility.ClearProgressBar(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } }