107 lines
3.7 KiB
C#
107 lines
3.7 KiB
C#
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");
|
|
}
|
|
|
|
}
|
|
}
|