using System.Collections.Generic; using Performance.Data; using UnityEditor; using UnityEngine; namespace Performance { public class AutoObjCombine { private GameObject _rootObj; private Dictionary _shaderCombinerDic = new Dictionary(); private string _savePath; private string _objName; public AutoObjCombine(GameObject rootObj) { _rootObj = rootObj; _objName = _rootObj.name; } public void DoCombine(string savePath) { _savePath = savePath; _ProtectPath(); _CollectAllRenderers(); _CombineToNewObj(); } private void _ProtectPath() { if (!_savePath.EndsWith("/")) { _savePath += "/"; } _savePath += _rootObj.name + "_Combined"; AssetDatabase.DeleteAsset(_savePath); } private void _CombineToNewObj() { var newObj = Object.Instantiate(_rootObj); // 删除所有meshrenderderers和meshfilters var allMeshRenderers = newObj.GetComponentsInChildren(); var allMeshFilters = newObj.GetComponentsInChildren(); for (int i = 0; i < allMeshRenderers.Length; i++) { Object.DestroyImmediate(allMeshRenderers[i]); } for (int i = 0; i < allMeshFilters.Length; i++) { Object.DestroyImmediate(allMeshFilters[i]); } foreach (var kvp in _shaderCombinerDic) { var combineObj = kvp.Value.CombineToSingleObject(_savePath, new List()); if (combineObj == null) { DebugUtil.LogError("合并对象失败, 可能是没有找到 MeshFilter 或 MeshRenderer"); continue; } combineObj.transform.SetParent(newObj.transform); } // 确保_savePath存在, 是从Assets目录开始的 if (!AssetDatabase.IsValidFolder(_savePath)) { var realPath = Application.dataPath + "/" + _savePath.Replace("Assets/", ""); System.IO.Directory.CreateDirectory(realPath); } // 把newObj保存到指定路径 var prefabPath = _savePath + "/" + _objName + ".prefab"; PrefabUtility.SaveAsPrefabAsset(newObj, prefabPath); // 清理新创建的 GameObject Object.DestroyImmediate(newObj); AssetDatabase.Refresh(); } private void _CollectAllRenderers() { var allMeshRenderers = _rootObj.GetComponentsInChildren(); for (int i = 0; i < allMeshRenderers.Length; i++) { var meshRenderer = allMeshRenderers[i]; if (meshRenderer == null || meshRenderer.sharedMaterial == null) { continue; } var shader = meshRenderer.sharedMaterial.shader; if (!_shaderCombinerDic.TryGetValue(shader, out var combiner)) { combiner = new ShaderGroupCombiner(shader); _shaderCombinerDic[shader] = combiner; } combiner.AddRenderer(meshRenderer); } DebugUtil.Log($"共收集到 {allMeshRenderers.Length} 个 MeshRenderer, 分别属于 {_shaderCombinerDic.Count} 个 Shader"); } } }