ClientServer/Client/Assets/Scripts/Util/Mesh/MeshCombinerStart.cs
TG9six 03a642d635 first push
first push
2025-09-06 17:17:39 +04:00

154 lines
5.7 KiB
C#

using System;
using System.Collections.Generic;
using NaughtyAttributes;
using UnityEditor;
using UnityEngine;
namespace Util.Mesh
{
public class MeshCombinerStart : MonoBehaviour
{
[SerializeField] private MeshCombiner meshCombiner;
private void Start()
{
meshCombiner.CombineMeshes(true);
}
private int GetTotalPolygons(Transform parent, MeshCombiner combiner)
{
MeshFilter[] meshFilters = combiner.GetMeshFiltersToCombine();
MeshRenderer[] meshRenderers = new MeshRenderer[meshFilters.Length];
meshRenderers[0] = GetComponent<MeshRenderer>(); // Our (parent) MeshRenderer.
List<Material> uniqueMaterialsList = new List<Material>();
for (int i = 0; i < meshFilters.Length - 1; i++)
{
meshRenderers[i + 1] = meshFilters[i + 1].GetComponent<MeshRenderer>();
if (meshRenderers[i + 1] != null)
{
Material[] materials = meshRenderers[i + 1].sharedMaterials; // Get all Materials from child Mesh.
for (int j = 0; j < materials.Length; j++)
{
if (!uniqueMaterialsList
.Contains(materials[j])) // If Material doesn't exists in the list then add it.
{
uniqueMaterialsList.Add(materials[j]);
}
}
}
}
List<CombineInstance> finalMeshCombineInstancesList = new List<CombineInstance>();
long verticesLength = 0;
for (int i = 0;
i < uniqueMaterialsList.Count;
i++) // Create each Mesh (submesh) from Meshes with the same Material.
{
List<CombineInstance> submeshCombineInstancesList = new List<CombineInstance>();
for (int j = 0; j < meshFilters.Length - 1; j++) // Get only childeren Meshes (skip our Mesh).
{
if (meshRenderers[j + 1] != null)
{
Material[] submeshMaterials =
meshRenderers[j + 1].sharedMaterials; // Get all Materials from child Mesh.
for (int k = 0; k < submeshMaterials.Length; k++)
{
if (uniqueMaterialsList[i] == submeshMaterials[k])
{
CombineInstance combineInstance = new CombineInstance();
combineInstance.subMeshIndex = k; // Mesh may consist of smaller parts - submeshes.
combineInstance.mesh = meshFilters[j + 1].sharedMesh;
combineInstance.transform = meshFilters[j + 1].transform.localToWorldMatrix;
submeshCombineInstancesList.Add(combineInstance);
verticesLength += combineInstance.mesh.vertices.Length;
}
}
}
}
}
return (int)verticesLength;
}
[Button("Get Value")]
public void GetValue()
{
if (meshCombiner == null) meshCombiner = GetComponent<MeshCombiner>();
var val = GetTotalPolygons(transform,meshCombiner);
if (val <= MeshCombiner.Mesh16BitBufferVertexLimit)
Debug.Log("<color=#00cc00><b>Mesh will created with "+val+" vertices</b></color>");
else
Debug.Log("<color=#ff3300><b>Mesh will created with "+val+" over 65535 vertices.</b></color>");
}
[Button("Combine")]
public void Combine()
{
if (meshCombiner == null) meshCombiner = GetComponent<MeshCombiner>();
meshCombiner.CreateMultiMaterialMesh = true;
meshCombiner.GenerateUVMap = true;
meshCombiner.CombineMeshes(true);
}
[Button("Split all Meshes")]
public void SplitMeshes()
{
var allMeshes = GetComponentsInChildren<MeshRenderer>();
foreach (var meshes in allMeshes)
{
SplitMesh(meshes);
}
Debugger.Logger($"Splited {gameObject.name}");
}
public void SplitMesh(MeshRenderer mesh)
{
MeshFilter mf = mesh.GetComponent<MeshFilter>();
MeshRenderer mr = mesh.GetComponent<MeshRenderer>();
if (mf == null || mr == null) return;
UnityEngine.Mesh originalMesh = mf.sharedMesh;
if (originalMesh == null || originalMesh.subMeshCount < 1) return;
int subMeshCount = originalMesh.subMeshCount;
var preset = new GameObject(mesh.name,typeof(MeshFilter), typeof(MeshRenderer));
for (int i = 0; i < subMeshCount; i++)
{
UnityEngine.Mesh newMesh = new UnityEngine.Mesh
{
vertices = originalMesh.vertices,
normals = originalMesh.normals,
uv = originalMesh.uv,
triangles = originalMesh.GetTriangles(i)
};
var part = Instantiate(preset, mesh.transform);
part.GetComponent<MeshFilter>().mesh = newMesh;
part.GetComponent<MeshRenderer>().sharedMaterial = (i < mr.sharedMaterials.Length) ? mr.sharedMaterials[i] : mr.sharedMaterial;
}
DestroyImmediate(preset);
// DestroyImmediate(mesh)?;
}
[Button("Center Mesh")]
void CenterMeshPivot()
{
UnityEngine.Mesh mesh = GetComponent<UnityEngine.MeshFilter>().sharedMesh;
Vector3 center = mesh.bounds.center;
Vector3[] vertices = mesh.vertices;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i] -= center;
}
mesh.vertices = vertices;
mesh.RecalculateBounds();
mesh.RecalculateNormals();
transform.position += center;
}
}
}