NLDClient-yudde/ProjectNLD/Assets/Editor/AutoCombine/Performance/AutoObjCombine.cs

107 lines
3.7 KiB
C#
Raw Normal View History

using System.Collections.Generic;
using Performance.Data;
using UnityEditor;
using UnityEngine;
namespace Performance
{
public class AutoObjCombine
{
private GameObject _rootObj;
private Dictionary<Shader, ShaderGroupCombiner> _shaderCombinerDic = new Dictionary<Shader, ShaderGroupCombiner>();
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<MeshRenderer>();
var allMeshFilters = newObj.GetComponentsInChildren<MeshFilter>();
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<Material>());
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<MeshRenderer>();
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");
}
}
}