NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/GameWrapper/LTCombie.cs

139 lines
6.3 KiB
C#
Raw Normal View History

2023-11-23 16:59:31 +08:00
using UnityEngine;
namespace Code.Scripts.Gameplay.Utils
{
public class LTCombie : MonoBehaviour
{
private Mesh _CreateMeshFromSubMesh(Mesh sourceMesh, int subMeshIndex)
{
// 创建一个新的网格
Mesh newMesh = new Mesh();
var subMeshDescriptor = sourceMesh.GetSubMesh(subMeshIndex);
// 获取来源网格的顶点、法线、切线和UV数组
Vector3[] vertices = sourceMesh.vertices;
Vector3[] normals = sourceMesh.normals;
Vector4[] tangents = sourceMesh.tangents;
Vector2[] uv = sourceMesh.uv;
// 从来源网格中获取指定子网格的三角形索引数组
int[] triangles = sourceMesh.GetTriangles(subMeshIndex);
// 根据子网格描述符中的顶点数量创建新网格的顶点、法线、切线和UV数组
Vector3[] newVertices = new Vector3[subMeshDescriptor.vertexCount];
Vector3[] newNormals = new Vector3[subMeshDescriptor.vertexCount];
Vector4[] newTangents = new Vector4[subMeshDescriptor.vertexCount];
Vector2[] newUV = new Vector2[subMeshDescriptor.vertexCount];
// 根据子网格描述符中的三角形索引数量,创建新网格的三角形索引数组
int[] newTriangles = new int[triangles.Length];
// 从来源网格的数组中复制数据到新网格的数组
for (int i = 0; i < subMeshDescriptor.vertexCount; i++)
{
newVertices[i] = vertices[subMeshDescriptor.firstVertex + i];
newNormals[i] = normals[subMeshDescriptor.firstVertex + i];
newTangents[i] = tangents[subMeshDescriptor.firstVertex + i];
newUV[i] = uv[subMeshDescriptor.firstVertex + i];
}
for (int i = 0; i < subMeshDescriptor.indexCount; i++)
{
newTriangles[i] = triangles[i] - subMeshDescriptor.firstVertex;
}
// 设置新网格的顶点、法线、切线和UV数组以及三角形索引数组
newMesh.vertices = newVertices;
newMesh.normals = newNormals;
newMesh.tangents = newTangents;
newMesh.uv = newUV;
newMesh.triangles = newTriangles;
return newMesh;
}
[ContextMenu("ManualCombine")]
public void ManualCombine()
{
// combine branch
{
var allMeshRenders = GetComponentsInChildren<MeshRenderer>();
var material = allMeshRenders[0].sharedMaterials[0];
var combineInstanceArrays = new CombineInstance[allMeshRenders.Length];
for (var i = 0; i < allMeshRenders.Length; i++)
{
var meshFilter = allMeshRenders[i].GetComponent<MeshFilter>();
var getMesh = meshFilter.sharedMesh;
combineInstanceArrays[i].mesh = _CreateMeshFromSubMesh(getMesh, 0);
combineInstanceArrays[i].transform = meshFilter.transform.localToWorldMatrix;
}
var newMesh = new Mesh();
newMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
newMesh.CombineMeshes(combineInstanceArrays, true, true);
var newGameObject = new GameObject("CombinedMesh_branch");
var newMeshFilter = newGameObject.AddComponent<MeshFilter>();
newMeshFilter.sharedMesh = newMesh;
var newMeshRenderer = newGameObject.AddComponent<MeshRenderer>();
newMeshRenderer.sharedMaterial = material;
newGameObject.transform.localPosition = Vector3.zero;
newGameObject.transform.localRotation = Quaternion.identity;
newGameObject.transform.localScale = Vector3.one;
// transform.gameObject.SetActive(false);
#if UNITY_EDITOR
// save mesh to asset
UnityEditor.AssetDatabase.CreateAsset(newMesh, "Assets/CombinedMesh_branch.asset");
UnityEditor.AssetDatabase.SaveAssets();
// save prefab to asset
UnityEditor.PrefabUtility.SaveAsPrefabAsset(newGameObject, "Assets/CombinedMesh_branch.prefab");
#endif
}
// combine trunk
{
var allMeshRenders = GetComponentsInChildren<MeshRenderer>();
var material = allMeshRenders[0].sharedMaterials[1];
var combineInstanceArrays = new CombineInstance[allMeshRenders.Length];
for (var i = 0; i < allMeshRenders.Length; i++)
{
var meshFilter = allMeshRenders[i].GetComponent<MeshFilter>();
var getMesh = meshFilter.sharedMesh;
combineInstanceArrays[i].mesh = _CreateMeshFromSubMesh(getMesh, 1);
combineInstanceArrays[i].transform = meshFilter.transform.localToWorldMatrix;
}
var newMesh = new Mesh();
newMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
newMesh.CombineMeshes(combineInstanceArrays, true, true);
var newGameObject = new GameObject("CombinedMesh_trunk");
var newMeshFilter = newGameObject.AddComponent<MeshFilter>();
newMeshFilter.sharedMesh = newMesh;
var newMeshRenderer = newGameObject.AddComponent<MeshRenderer>();
newMeshRenderer.sharedMaterial = material;
newGameObject.transform.localPosition = Vector3.zero;
newGameObject.transform.localRotation = Quaternion.identity;
newGameObject.transform.localScale = Vector3.one;
#if UNITY_EDITOR
// save mesh to asset
UnityEditor.AssetDatabase.CreateAsset(newMesh, "Assets/CombinedMesh_trunk.asset");
UnityEditor.AssetDatabase.SaveAssets();
// save prefab to asset
UnityEditor.PrefabUtility.SaveAsPrefabAsset(newGameObject, "Assets/CombinedMesh_trunk.prefab");
#endif
}
transform.gameObject.SetActive(false);
}
}
}