210 lines
6.7 KiB
C#
210 lines
6.7 KiB
C#
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)
|
|
{
|
|
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<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;
|
|
}
|
|
} |