public void Deserialize(Stream stream, BinaryReader reader) { name = reader.ReadString(); hideFlags = reader.ReadInt32(); vertices = reader.ReadVector3Array(); subMeshCount = reader.ReadInt32(); m_tris = new IntArray[reader.ReadInt32()]; for (int i = 0; i < m_tris.Length; ++i) { m_tris[i] = new IntArray { Array = reader.ReadInt32Array() }; } indexFormat = (UnityEngine.Rendering.IndexFormat)reader.ReadInt32(); m_topology = new MeshTopology[reader.ReadInt32()]; for (int i = 0; i < m_topology.Length; ++i) { m_topology[i] = (MeshTopology)reader.ReadInt32(); } boneWeights = reader.ReadBoneWeightsArray(); bindposes = reader.ReadMatrixArray(); bounds = reader.ReadBounds(); normals = reader.ReadVector3Array(); tangents = reader.ReadVector4Array(); colors = reader.ReadColorArray(); uv = reader.ReadVector2Array(); uv2 = reader.ReadVector2Array(); uv3 = reader.ReadVector2Array(); uv4 = reader.ReadVector2Array(); uv5 = reader.ReadVector2Array(); uv6 = reader.ReadVector2Array(); uv7 = reader.ReadVector2Array(); uv8 = reader.ReadVector2Array(); }
public ImportSettings(bool isPreImport) { PathToObj = ""; MSI = new MeshSequenceInfo("", MeshSequenceInfo.SortModeEnum.ByNumber); ImportCustomRange = false; ImportFromFrame = 0; ImportToFrame = 1; SwapYZAxis = false; PivotOffset = Vector3.zero; ScaleFactor = 1; FlipNormals = false; ImportUV = true; CalculateNormals = true; CalculateTangents = true; SmoothingGroupImportMode = ObjData.SmoothingGroupImportModeEnum.FromObjFile; NormalRecalculationMode = ObjData.NormalsRecalculationModeEnum.Default; MeshCompression = 0; OptimizeMesh = false; #if UNITY_2017_3_OR_NEWER IndexFormat = UnityEngine.Rendering.IndexFormat.UInt16; #endif GenerateMaterials = true; VColorSettings = new ObjData.VertexColorsSettings(false); NormalizedPerFrame = 0; FilesSortMode = MeshSequenceInfo.SortModeEnum.ByNumber; ImportDate = "none"; }
public override void ReadFrom(object obj) { base.ReadFrom(obj); if (obj == null) { return; } Mesh o = (Mesh)obj; indexFormat = o.indexFormat; subMeshCount = o.subMeshCount; if (o.vertices != null) { vertices = new PersistentVector3[o.vertices.Length]; for (int i = 0; i < o.vertices.Length; ++i) { PersistentVector3 v = new PersistentVector3(); v.ReadFrom(o.vertices[i]); vertices[i] = v; } } m_tris = new IntArray[subMeshCount]; for (int i = 0; i < subMeshCount; ++i) { m_tris[i] = new IntArray(); m_tris[i].Array = o.GetTriangles(i); } }
public override void ReadFrom(object obj) { base.ReadFrom(obj); if (obj == null) { return; } Mesh o = (Mesh)obj; if (!m_assetDB.IsStaticResourceID(m_assetDB.ToID(o))) { boneWeights = o.boneWeights; bindposes = o.bindposes; bounds = o.bounds; normals = o.normals; tangents = o.tangents; uv = o.uv; uv2 = o.uv2; uv3 = o.uv3; uv4 = o.uv4; uv5 = o.uv5; uv6 = o.uv6; uv7 = o.uv7; uv8 = o.uv8; colors = o.colors; indexFormat = o.indexFormat; subMeshCount = o.subMeshCount; if (o.vertices != null) { vertices = o.vertices; } m_tris = new IntArray[subMeshCount]; m_topology = new MeshTopology[subMeshCount]; for (int i = 0; i < subMeshCount; ++i) { MeshTopology topology = o.GetTopology(i); m_topology[i] = topology; switch (topology) { case MeshTopology.Points: m_tris[i] = new IntArray(); m_tris[i].Array = o.GetIndices(i); break; case MeshTopology.Lines: m_tris[i] = new IntArray(); m_tris[i].Array = o.GetIndices(i); break; case MeshTopology.Triangles: m_tris[i] = new IntArray(); m_tris[i].Array = o.GetTriangles(i); break; } } } }
/// <summary> /// Calculate the index format based on number of vertices. /// </summary> public void CalculateIndexFormat(int numVertices) { uint maxVertexCount = ushort.MaxValue; uint vertexCount = Convert.ToUInt32(numVertices); if (vertexCount > maxVertexCount) { #if UNITY_2017_3_OR_NEWER // For vertex count larger than 16-bit, use 32-bit buffer _indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; #else Debug.LogErrorFormat("Vertex count {0} which is above Unity maximum of {1}.\nUse Unity 2017.3+ or reduce this in Houdini.", vertexCount, maxVertexCount); #endif } }
public ImportSettings(int usedClipsCount) { SwapYZAxis = false; ScaleFactor = 1f; FlipNormals = false; SmoothingGroupImportMode = ObjData.SmoothingGroupImportModeEnum.FromObjFile; NormalRecalculationMode = ObjData.NormalsRecalculationModeEnum.Default; MeshCompression = 0; OptimizeMesh = false; UsedClipsCount = usedClipsCount; UsedMeshesCount = 1; GenerateMaterials = true; SavePortableData = false; #if UNITY_2017_3_OR_NEWER IndexFormat = UnityEngine.Rendering.IndexFormat.UInt16; #endif }
public override void ReadFrom(object obj) { base.ReadFrom(obj); if (obj == null) { return; } Mesh o = (Mesh)obj; indexFormat = o.indexFormat; subMeshCount = o.subMeshCount; vertices = o.vertices; m_tris = new IntArray[subMeshCount]; for (int i = 0; i < subMeshCount; ++i) { m_tris[i] = new IntArray(); m_tris[i].Array = o.GetTriangles(i); } }
void Awake() { Instance = this; if (NoLimit) { indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; MaxVertex = int.MaxValue; } else { if (MaxVertex > 65535) { indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; } } CombinedMesh.indexFormat = indexFormat; CombinedMesh.MaxVertex = MaxVertex; }
public override void ReadFrom(object obj) { base.ReadFrom(obj); if (obj == null) { return; } Mesh o = (Mesh)obj; indexFormat = o.indexFormat; subMeshCount = o.subMeshCount; if (o.vertices != null) { vertices = o.vertices; } m_tris = new IntArray[subMeshCount]; m_topology = new MeshTopology[subMeshCount]; for (int i = 0; i < subMeshCount; ++i) { MeshTopology topology = o.GetTopology(i); m_topology[i] = topology; switch (topology) { case MeshTopology.Points: m_tris[i] = new IntArray(); m_tris[i].Array = o.GetIndices(i); break; case MeshTopology.Lines: m_tris[i] = new IntArray(); m_tris[i].Array = o.GetIndices(i); break; case MeshTopology.Triangles: m_tris[i] = new IntArray(); m_tris[i].Array = o.GetTriangles(i); break; } } }
UpdateMeshData( Vector3[] positions, Vector3[] normals, List <List <Vector2> > uvs, int numFacesets, List <int[]> indices, UnityEngine.Rendering.IndexFormat indexFormat, ref Mesh mesh) { // specify some vertices mesh.vertices = positions; mesh.normals = normals; mesh.indexFormat = indexFormat; // set each UV set // mesh class assumes that each uv is corresponding to the polygon vertex // indice, so we are not using uv indices provided by STP for (var i = 0; i < uvs.Count; i++) { mesh.SetUVs(i, uvs[i]); } // must call this before assigning indices through SetTriangles or Unity won't notice > 1 submeshes mesh.subMeshCount = numFacesets; // per face-set indices for (var i = 0; i < numFacesets; ++i) { // Flip array of indices to account for cordinate system change FlipWindingArray(indices[i], indices[i].Length); mesh.SetTriangles(indices[i], i); } if (null == normals) { // only recalculate normals when there are none mesh.RecalculateNormals(); } mesh.RecalculateTangents(); // we never pass tangents, so let's build them (in case any shader requires them) return(true); }
public override void ReadFrom(object obj) { base.ReadFrom(obj); if (obj == null) { return; } Mesh o = (Mesh)obj; if (!m_assetDB.IsStaticResourceID(m_assetDB.ToID(o))) { boneWeights = o.boneWeights; bindposes = o.bindposes; bounds = o.bounds; normals = o.normals; tangents = o.tangents; uv = o.uv; uv2 = o.uv2; uv3 = o.uv3; uv4 = o.uv4; uv5 = o.uv5; uv6 = o.uv6; uv7 = o.uv7; uv8 = o.uv8; colors = o.colors; indexFormat = o.indexFormat; subMeshCount = o.subMeshCount; if (o.vertices != null) { vertices = o.vertices; } m_tris = new IntArray[subMeshCount]; m_topology = new MeshTopology[subMeshCount]; for (int i = 0; i < subMeshCount; ++i) { MeshTopology topology = o.GetTopology(i); m_topology[i] = topology; switch (topology) { case MeshTopology.Points: m_tris[i] = new IntArray(); m_tris[i].Array = o.GetIndices(i); break; case MeshTopology.Lines: m_tris[i] = new IntArray(); m_tris[i].Array = o.GetIndices(i); break; case MeshTopology.Triangles: m_tris[i] = new IntArray(); m_tris[i].Array = o.GetTriangles(i); break; } } blendShapeCount = o.blendShapeCount; if (blendShapeCount > 0) { blendShapeNames = new string[blendShapeCount]; blendShapeFrameCount = new int[blendShapeCount]; blendShapeFrames = new List <PersistentBlendShapeFrame <TID> >(); int vertexCount = o.vertexCount; for (int shapeIndex = 0; shapeIndex < blendShapeCount; ++shapeIndex) { int frameCount = o.GetBlendShapeFrameCount(shapeIndex); blendShapeFrameCount[shapeIndex] = frameCount; string blendShapeName = o.GetBlendShapeName(shapeIndex); blendShapeNames[shapeIndex] = blendShapeName; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { float weight = o.GetBlendShapeFrameWeight(shapeIndex, frameIndex); Vector3[] deltaVertices = new Vector3[vertexCount]; Vector3[] deltaNormals = new Vector3[vertexCount]; Vector3[] deltaTangents = new Vector3[vertexCount]; o.GetBlendShapeFrameVertices(shapeIndex, frameIndex, deltaVertices, deltaNormals, deltaTangents); PersistentBlendShapeFrame <TID> frame = new PersistentBlendShapeFrame <TID>(weight, deltaVertices, deltaNormals, deltaTangents); blendShapeFrames.Add(frame); } } } } }
//Create a light mesh object. Cram as much lights as you can into the LightData array. If there are too many lights for one GameObject, it will //automatically be split into multiple objects. //When creating city lights, use the function overload which takes a position array instead of a lightData array. private static GameObject[] CreateLightsAll(string name, LightData[] lightData, Vector3[] positions, float simpleShaderLightSize, Material material, UnityEngine.Rendering.IndexFormat meshIndexFormat) { int transformAmount = 0; if (lightData != null) { transformAmount = lightData.Length; } else { transformAmount = positions.Length; } int lightsInThisBatch; int maxTriangles; if (meshIndexFormat == UnityEngine.Rendering.IndexFormat.UInt32) { maxTriangles = maxTriangls32; } else { maxTriangles = maxTriangls16; } //The triangle limit is 21844 (16 bit) or 1431655765 (32 bit) per mesh, so split the objects up if needed. int meshAmount = (int)Mathf.Ceil(transformAmount / (float)maxTriangles); GameObject[] lightObjects = new GameObject[meshAmount]; //Get the remainder. int remainder = (int)(transformAmount % (float)maxTriangles); //Loop through the mesh batches. for (int l = 0; l < meshAmount; l++) { //Get the amount of lights in this mesh batch. if (meshAmount == 1) { lightsInThisBatch = transformAmount; } else { //Last mesh batch. if (l == (meshAmount - 1)) { if (remainder == 0) { lightsInThisBatch = maxTriangles; } else { lightsInThisBatch = remainder; } } else { lightsInThisBatch = maxTriangles; } } bool directional = false; bool omnidirectional = false; bool strobe = false; bool papi = false; bool simple = false; int vertexCount = lightsInThisBatch * 3; Vector4[] corners = new Vector4[vertexCount]; Vector2[] uvs = new Vector2[vertexCount]; Vector4[] triangleCorners = new Vector4[3]; Vector2[] triangleUvs = new Vector2[3]; Vector3[] normals = null; Vector3 normal = Vector3.one; Vector3 right = Vector3.one; Vector3 up = Vector3.one; //Create temporary arrays. Vector3[] centers = new Vector3[vertexCount]; int[] triangles = new int[vertexCount]; int[] indices = new int[vertexCount]; Vector2[] uv2Channel = null; Vector2[] uv3Channel = null; Vector2[] uv4Channel = null; Color[] colorChannel = null; Vector4 corner0 = Vector4.zero; Vector4 corner1 = Vector4.zero; Vector4 corner2 = Vector4.zero; //Generate a triangle which fits over a quad. //Taken out of the function for performance. //GenerateTriangle(out triangleCorners, out triangleUvs); //Set the points, counter clockwise as an upright triangle, with the left //corner as point 0, right corner point 1, and top is point 2. //X and Y are computed like this: //x = (1f / Mathf.Tan(60f * Mathf.Deg2Rad)) + 0.5f; //y = // (0.5f / Mathf.Tan(30f * Mathf.Deg2Rad)) + 0.5f; triangleCorners[0] = new Vector4(-1.07735f, -0.5f, 0.0f, 1.0f); triangleCorners[1] = new Vector4(1.07735f, -0.5f, 0.0f, 1.0f); triangleCorners[2] = new Vector4(0.0f, 1.366025f, 0.0f, 1.0f); //Computed like this: //float u = Math3d.NormalizeComplex(localPoints[i].x, -0.5f, 0.5f); //float v = Math3d.NormalizeComplex(localPoints[i].y, -0.5f, 0.5f); triangleUvs[0].x = -0.57735f; triangleUvs[0].y = 0f; triangleUvs[1].x = 1.57735f; triangleUvs[1].y = 0f; triangleUvs[2].x = 0.5f; triangleUvs[2].y = 1.866025f; if (lightData != null) { normals = new Vector3[vertexCount]; //What is stored in here, depends on the shader. uv2Channel = new Vector2[vertexCount]; uv3Channel = new Vector2[vertexCount]; uv4Channel = new Vector2[vertexCount]; colorChannel = new Color[vertexCount]; if (material.shader.name.Contains("Directional")) { directional = true; } if (material.shader.name.Contains("Omnidirectional")) { omnidirectional = true; } if (material.shader.name.Contains("Strobe")) { strobe = true; } if (material.shader.name.Contains("PAPI")) { papi = true; } } else { simple = true; corner0 = new Vector4(triangleCorners[0].x, triangleCorners[0].y, triangleCorners[0].z, simpleShaderLightSize); corner1 = new Vector4(triangleCorners[1].x, triangleCorners[1].y, triangleCorners[1].z, simpleShaderLightSize); corner2 = new Vector4(triangleCorners[2].x, triangleCorners[2].y, triangleCorners[2].z, simpleShaderLightSize); } //Loop through all the lights and set them up. for (int i = 0; i < lightsInThisBatch; i++) { float size = 0; int e = i * 3; int e1 = e + 1; int e2 = e + 2; int index = (l * maxTriangles) + i; if (lightData != null) { size = lightData[index].size; centers[e] = lightData[index].position; centers[e1] = lightData[index].position; centers[e2] = lightData[index].position; corners[e] = new Vector4(triangleCorners[0].x, triangleCorners[0].y, triangleCorners[0].z, size); corners[e1] = new Vector4(triangleCorners[1].x, triangleCorners[1].y, triangleCorners[1].z, size); corners[e2] = new Vector4(triangleCorners[2].x, triangleCorners[2].y, triangleCorners[2].z, size); } else { size = simpleShaderLightSize; centers[e] = positions[index]; centers[e1] = positions[index]; centers[e2] = positions[index]; corners[e] = corner0; corners[e1] = corner1; corners[e2] = corner2; } uvs[e] = triangleUvs[0]; uvs[e1] = triangleUvs[1]; uvs[e2] = triangleUvs[2]; if (lightData != null) { if (papi || omnidirectional) { up = Math3d.GetUpVector(lightData[index].rotation); } if (!simple) { normal = -Math3d.GetForwardVector(lightData[index].rotation); normals[e] = normal; normals[e1] = normal; normals[e2] = normal; } if (papi) { right = Math3d.GetRightVector(lightData[index].rotation); uv2Channel[e] = right; uv2Channel[e1] = right; uv2Channel[e2] = right; uv3Channel[e] = up; uv3Channel[e1] = up; uv3Channel[e2] = up; //Compose the z vector. Vector2 zVector = new Vector2(right.z, up.z); uv4Channel[e] = zVector; uv4Channel[e1] = zVector; uv4Channel[e2] = zVector; } if (directional) { //Create the back color. Vector2 RG = new Vector2(lightData[index].backColor.r, lightData[index].backColor.g); Vector2 BA = new Vector2(lightData[index].backColor.b, lightData[index].backColor.a); uv2Channel[e] = RG; uv2Channel[e1] = RG; uv2Channel[e2] = RG; uv3Channel[e] = BA; uv3Channel[e1] = BA; uv3Channel[e2] = BA; } if (omnidirectional) { //Create the back color. Vector2 RG = new Vector2(lightData[index].backColor.r, lightData[index].backColor.g); uv2Channel[e] = RG; uv2Channel[e1] = RG; uv2Channel[e2] = RG; uv3Channel[e] = up; uv3Channel[e1] = up; uv3Channel[e2] = up; //Compose the z vector. The x component is used for the blue component of the back color. Vector2 zVector = new Vector2(lightData[index].backColor.b, up.z); uv4Channel[e] = zVector; uv4Channel[e1] = zVector; uv4Channel[e2] = zVector; } if (strobe) { //Store the light and group id in the color channel. Color id = new Color(lightData[index].strobeID, lightData[index].strobeGroupID, 0, 0); colorChannel[e] = id; colorChannel[e1] = id; colorChannel[e2] = id; } if (directional || omnidirectional) { //Create the front color. Note that the light brightness value is stored in the alpha channel. Color frontColor = new Color(lightData[index].frontColor.r, lightData[index].frontColor.g, lightData[index].frontColor.b, lightData[index].brightness); colorChannel[e] = frontColor; colorChannel[e1] = frontColor; colorChannel[e2] = frontColor; } } triangles[e] = e; triangles[e1] = e1; triangles[e2] = e2; indices[e] = e; indices[e1] = e1; indices[e2] = e2; } //Create a new gameObject. GameObject lightObject = new GameObject(name + " " + l); lightObjects[l] = lightObject; //Add the required components to the game object. MeshFilter meshFilter = lightObject.AddComponent <MeshFilter>(); MeshRenderer meshRenderer = lightObject.AddComponent <MeshRenderer>(); //Create a new mesh. meshFilter.sharedMesh = new Mesh(); //Apply the mesh properties. meshFilter.sharedMesh.indexFormat = meshIndexFormat; meshFilter.sharedMesh.vertices = centers; meshFilter.sharedMesh.tangents = corners; //The mesh corner is stored in the tangent channel. The scale is stored in the w component. meshFilter.sharedMesh.uv = uvs; meshFilter.sharedMesh.triangles = triangles; if (!simple) { meshFilter.sharedMesh.normals = normals; meshFilter.sharedMesh.colors = colorChannel; //Front color for directional lights. Alpha is the brightness reduction. //ID for strobe lights. meshFilter.sharedMesh.uv2 = uv2Channel; //RG(BA) back color for directional lights. //Rotation vector for omnidirectional lights and PAPIs. meshFilter.sharedMesh.uv3 = uv3Channel; //(RG)BA back color for directional lights. Alpha is for invisibility. //Rotation vector for omnidirectional lights and PAPIS. meshFilter.sharedMesh.uv4 = uv4Channel; //The UV channels only hold two floats, so use a third UV channel to store the Z components of the vectors. } //Set the indices. meshFilter.sharedMesh.SetIndices(indices, MeshTopology.Triangles, 0); //Set the gameObject properties; meshRenderer.sharedMaterial = material; meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; meshRenderer.receiveShadows = false; meshRenderer.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; meshRenderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; } return(lightObjects); }
//Overload for all other lights. public static GameObject[] CreateLights(string name, LightData[] lightData, Material material, UnityEngine.Rendering.IndexFormat meshIndexFormat) { GameObject[] lightObjects = CreateLightsAll(name, lightData, null, 0, material, meshIndexFormat); return(lightObjects); }
//Overload for city lights (simple shader) public static GameObject[] CreateLights(string name, Vector3[] positions, float size, Material material, UnityEngine.Rendering.IndexFormat meshIndexFormat) { GameObject[] lightObjects = CreateLightsAll(name, null, positions, size, material, meshIndexFormat); return(lightObjects); }
public void Combiner(Transform parent, GameObject finalMesh, bool destroy = true, UnityEngine.Rendering.IndexFormat format = UnityEngine.Rendering.IndexFormat.UInt32) { ArrayList materials = new ArrayList(); ArrayList combineInstanceArrays = new ArrayList(); MeshFilter[] meshFilters = parent.GetComponentsInChildren <MeshFilter>(); Matrix4x4 myTransform = parent.worldToLocalMatrix; foreach (MeshFilter meshFilter in meshFilters) { MeshRenderer meshRenderer = meshFilter.GetComponent <MeshRenderer>(); if (!meshRenderer || !meshFilter.sharedMesh || meshRenderer.sharedMaterials.Length != meshFilter.sharedMesh.subMeshCount) { continue; } for (int s = 0; s < meshFilter.sharedMesh.subMeshCount; s++) { int materialArrayIndex = Contains(materials, meshRenderer.sharedMaterials[s].name); if (materialArrayIndex == -1) { materials.Add(meshRenderer.sharedMaterials[s]); materialArrayIndex = materials.Count - 1; } combineInstanceArrays.Add(new ArrayList()); CombineInstance combineInstance = new CombineInstance(); combineInstance.transform = myTransform * meshRenderer.transform.localToWorldMatrix; combineInstance.subMeshIndex = s; combineInstance.mesh = meshFilter.sharedMesh; (combineInstanceArrays[materialArrayIndex] as ArrayList).Add(combineInstance); } } // Get / Create mesh filter & renderer MeshFilter meshFilterCombine = parent.gameObject.GetComponent <MeshFilter>(); if (meshFilterCombine == null) { meshFilterCombine = parent.gameObject.AddComponent <MeshFilter>(); } MeshRenderer meshRendererCombine = parent.GetComponent <MeshRenderer>(); if (meshRendererCombine == null) { meshRendererCombine = parent.gameObject.AddComponent <MeshRenderer>(); } // Combine by material index into per-material meshes // also, Create CombineInstance array for next step Mesh[] meshes = new Mesh[materials.Count]; CombineInstance[] combineInstances = new CombineInstance[materials.Count]; int m = 0; for (m = 0; m < materials.Count; m++) { CombineInstance[] combineInstanceArray = (combineInstanceArrays[m] as ArrayList).ToArray(typeof(CombineInstance)) as CombineInstance[]; meshes[m] = GetMesh(); meshes[m].indexFormat = format; meshes[m].CombineMeshes(combineInstanceArray, true, true); combineInstances[m] = new CombineInstance(); combineInstances[m].mesh = meshes[m]; combineInstances[m].subMeshIndex = 0; } // Combine into one meshFilterCombine.sharedMesh = GetMesh(); meshFilterCombine.sharedMesh.CombineMeshes(combineInstances, false, false); actualMeshes.Remove(meshFilterCombine.sharedMesh); // Destroy other meshes /* * foreach (Mesh oldMesh in meshes) * { * oldMesh.Clear(); * DestroyImmediate( oldMesh,false ); * }*/ //Make other meshes available foreach (Mesh mmeesshh in actualMeshes.ToArray()) { mmeesshh.Clear(); actualMeshes.Remove(mmeesshh); availableMeshes.Add(mmeesshh); } // Assign materials Material[] materialsArray = materials.ToArray(typeof(Material)) as Material[]; meshRendererCombine.materials = materialsArray; if (destroy) { foreach (MeshFilter meshFilter in meshFilters) { if (meshFilter.gameObject != null) { DestroyImmediate(meshFilter.gameObject); } } } }