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

210 lines
6.7 KiB
C#
Raw Normal View History

using System.Collections;
using System.Collections.Generic;
using Performance.Data;
using PhxhSDK;
using UnityEngine;
public class SceneCombineUtil : Singlenton<SceneCombineUtil>
{
private int _totalCount;
private List<AutoCombieMeshData> _cacheMeshes = new List<AutoCombieMeshData>();
private List<ShaderGroupCombiner> _cacheShaders = new List<ShaderGroupCombiner>();
private List<Material> _sampleMaterials = new List<Material>();
private int _forceUnitTextureSize = 256;
public List<GameObject> CombineGameObjectsByGroups(Dictionary<string, List<Renderer>> rendererGroups,
Transform root,
string outputPath,
int postProcessTextureUnitSize = 256,
List<Material> sampleMaterials = null,string prefix = "")
{
if (sampleMaterials != null)
{
_sampleMaterials.AddRange(sampleMaterials);
}
_forceUnitTextureSize = postProcessTextureUnitSize;
List<GameObject> result = new List<GameObject>();
foreach (var group in rendererGroups)
{
string groupName = group.Key;
List<Renderer> 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<GameObject> CombineGameObjects(List<Renderer> renderers,
Transform root,
string outputPath,
int postProcessTextureUnitSize = 256,
List<Material> sampleMaterials = null, string prefix = "")
{
var rendererGroups = new Dictionary<string, List<Renderer>>
{
{ "Default", renderers }
};
return CombineGameObjectsByGroups(rendererGroups, root, outputPath, postProcessTextureUnitSize, sampleMaterials, prefix);
}
private List<GameObject> _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<GameObject> 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<Renderer> renderers, string groupName = "Default")
{
_cacheShaders.Clear();
foreach (var renderer in renderers)
{
2026-03-09 16:29:43 +08:00
var objPath = renderer.gameObject.GetFullPath();
var materials = renderer.sharedMaterials;
if (materials.Length > 1)
{
2026-03-09 16:29:43 +08:00
Debug.LogError($"[SceneCombine] 材质数量大于1 (共{materials.Length}个) | 物体: {objPath} | Group: {groupName}", renderer.gameObject);
continue;
}
var shareMaterial = renderer.sharedMaterial;
if (shareMaterial == null)
{
2026-03-09 16:29:43 +08:00
Debug.LogError($"[SceneCombine] 没有材质 | 物体: {objPath} | Group: {groupName}", renderer.gameObject);
continue;
}
var shader = shareMaterial.shader;
if (shader == null)
{
2026-03-09 16:29:43 +08:00
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<Renderer> _CollectRenderers(List<GameObject> gameObjects)
{
var result = new List<Renderer>();
foreach (var go in gameObjects)
{
var renderer = go.GetComponent<Renderer>();
if (renderer != null)
result.Add(renderer);
}
return result;
}
private void _CollectMeshs(List<Renderer> renderers)
{
_totalCount = 0;
_cacheMeshes.Clear();
foreach (var renderer in renderers)
{
var meshFilter = renderer.GetComponent<MeshFilter>();
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;
}
}