using System.Collections; using System.Collections.Generic; using Performance.Data; using PhxhSDK; using UnityEngine; public class SceneCombineUtil : Singlenton { private int _totalCount; private List _cacheMeshes = new List(); private List _cacheShaders = new List(); private List _sampleMaterials = new List(); private int _forceUnitTextureSize = 256; public List CombineGameObjectsByGroups(Dictionary> rendererGroups, Transform root, string outputPath, int postProcessTextureUnitSize = 256, List sampleMaterials = null,string prefix = "") { if (sampleMaterials != null) { _sampleMaterials.AddRange(sampleMaterials); } _forceUnitTextureSize = postProcessTextureUnitSize; List result = new List(); foreach (var group in rendererGroups) { string groupName = group.Key; List groupRenderers = group.Value; // 为每个组创建单独的输出路径 string groupOutputPath = $"{outputPath}"; // 收集该组的网格和着色器 _CollectMeshs(groupRenderers); _CollectShaders(groupRenderers, groupName); // 合并该组 var groupResult = _DoCombine(root, groupOutputPath, prefix); result.AddRange(groupResult); // 清理缓存,准备下一组 _cacheMeshes.Clear(); _cacheShaders.Clear(); } return result; } [System.Obsolete("Use CombineGameObjectsByGroups instead")] public List CombineGameObjects(List renderers, Transform root, string outputPath, int postProcessTextureUnitSize = 256, List sampleMaterials = null, string prefix = "") { var rendererGroups = new Dictionary> { { "Default", renderers } }; return CombineGameObjectsByGroups(rendererGroups, root, outputPath, postProcessTextureUnitSize, sampleMaterials, prefix); } private List _DoCombine(Transform root, string outputPath, string prefix = "") { // 强制替换 // if (_cacheRootObj == null) // { // var findObj = GameObject.Find("CombieRoot"); // if (findObj != null) // { // DestroyImmediate(findObj); // } // } // else // { // DestroyImmediate(_cacheRootObj); // } //_cacheRootObj = new GameObject("CombieRoot"); List result = new(); for (int i = 0; i < _cacheShaders.Count; i++) { var shaderData = _cacheShaders[i]; var combineObj = shaderData.CombineToSingleObject(outputPath, _sampleMaterials, prefix); if (combineObj != null) { result.Add(combineObj); combineObj.transform.SetParent(root); } //combieObj.transform.SetParent(_cacheRootObj.transform); } return result; // 隐藏原始节点 //_SetOldObjActive(false); //AssetDatabase.Refresh(); } private void _CollectShaders(List renderers, string groupName = "Default") { _cacheShaders.Clear(); foreach (var renderer in renderers) { var objPath = renderer.gameObject.GetFullPath(); var materials = renderer.sharedMaterials; if (materials.Length > 1) { Debug.LogError($"[SceneCombine] 材质数量大于1 (共{materials.Length}个) | 物体: {objPath} | Group: {groupName}", renderer.gameObject); continue; } var shareMaterial = renderer.sharedMaterial; if (shareMaterial == null) { Debug.LogError($"[SceneCombine] 没有材质 | 物体: {objPath} | Group: {groupName}", renderer.gameObject); continue; } var shader = shareMaterial.shader; if (shader == null) { Debug.LogError($"[SceneCombine] 材质没有Shader | 物体: {objPath} | 材质: {shareMaterial.name} | Group: {groupName}", renderer.gameObject); continue; } var shaderData = _GetShaderData(shader, groupName); shaderData.AddRenderer(renderer); } // 预计算贴图大小 foreach (var shaderData in _cacheShaders) { shaderData.PreCalculate(); } } private List _CollectRenderers(List gameObjects) { var result = new List(); foreach (var go in gameObjects) { var renderer = go.GetComponent(); if (renderer != null) result.Add(renderer); } return result; } private void _CollectMeshs(List renderers) { _totalCount = 0; _cacheMeshes.Clear(); foreach (var renderer in renderers) { var meshFilter = renderer.GetComponent(); if (meshFilter == null) { Debug.LogError(renderer.name + "没有MeshFilter", renderer.gameObject); continue; } var mesh = meshFilter.sharedMesh; if (mesh == null) { Debug.LogError(renderer.name + "没有Mesh", renderer.gameObject); continue; } var meshData = _GetMeshData(mesh); _totalCount += mesh.vertexCount; meshData.AddObj(renderer.gameObject); } } private ShaderGroupCombiner _GetShaderData(Shader shader, string groupName = "Default") { foreach (var shaderData in _cacheShaders) { if (shaderData.shader == shader && shaderData.groupName == groupName) { return shaderData; } } var newShaderData = new ShaderGroupCombiner(shader, _forceUnitTextureSize, groupName); _cacheShaders.Add(newShaderData); return newShaderData; } private AutoCombieMeshData _GetMeshData(Mesh mesh) { foreach (var meshData in _cacheMeshes) { if (meshData.mesh == mesh) { return meshData; } } var newMeshData = new AutoCombieMeshData(mesh); _cacheMeshes.Add(newMeshData); return newMeshData; } }