unity3d 移除具有Cloth组件的网格的三角形

klr1opcd  于 2023-03-13  发布在  其他
关注(0)|答案(1)|浏览(129)

我已经实现了移除三角形来移除选中的三角形,使用光线投射。我的实现可以很好地处理网格,因为网格没有布料的组件,但是当我添加布料组件时,我仍然可以移除三角形,但是有一个问题。它会移除三角形,当我停止游戏并重新运行它时,它正确地向我显示了结果,三角形的移除仍然可见,除非我重新启动统一。
我已经分享了几个截图,从开始到结束一步一步沿着代码。
1:Before running the scene
2:Removing the triangles of the mesh having cloth component using raycast
3:Stoped the scene
4:Re-run the scene and we can see the result of separation of plane after triangles removed vertically
我的目标是在运行时看到结果。我不知道我应该做什么或我的代码中有什么错误。我将感谢任何指导。提前感谢您。

using System;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using System.Numerics;
using Vector2 = UnityEngine.Vector2;
using Vector3 = UnityEngine.Vector3;
using Vector4 = UnityEngine.Vector4;



public  class RemoveTriangle : MonoBehaviour
{
   // [Header("Game Object")][Tooltip("The game object that will be removed its triangles")]
    //public GameObject spherePrefab;
    // Better to reference those already in the Inspector
    [Header("Mesh Files to Load")]
   /* [SerializeField][Tooltip("Drag and drop the mesh files you want to load")] private Obi.ObiBlueprintFilterMask meshFilter;
    [SerializeField][Tooltip("Drag and drop the mesh files you want to load")] private Obi.ObiParticleRenderer meshRenderer;
    [SerializeField][Tooltip("Drag and drop the mesh files you want to load")] private SkinnedMeshRenderer meshCollider;*/
    //[SerializeField] [Range(1.0f, 3.0f)] public float raycastSize = 1.0f;
    [Header("Origin and Target objects")]
    [Tooltip("Drag and drop the origin and target objects")]public Transform SelectOrigin;
    [Tooltip("Drag and drop the origin and target objects")] public  SkinnedMeshRenderer skinnedMeshRenderer;
    [Header("Raycast Distance")][Tooltip("The distance of the raycast")]
    [SerializeField][Range(0.1f,20.0f)]public float MaxDistance = 10f;

    public Mesh mesh;
    
   
    public bool useTethres;

    private void Start()
    {
        mesh = skinnedMeshRenderer.sharedMesh;
        

    }

    private void Update()
    {
        
        DeleteTriangle();
        

    }

    void DeleteTriangle()
    {//raycast from mouse position
        Mesh newMesh = new Mesh();
        
        
        if (Input.GetKey(KeyCode.C))
        {//raycast from mouse position
            Ray ray = new Ray(SelectOrigin.position, SelectOrigin.forward);
            RaycastHit hit;

           if(Physics.Raycast(ray, out hit, MaxDistance))
            {//if raycast hits a triangle
                Debug.DrawRay(SelectOrigin.position,
                            skinnedMeshRenderer.transform.forward - SelectOrigin.position, 
                             Color.red);
                Debug.Log("Triangle Removed at: " + hit.point + "/" + hit.triangleIndex + "/" + hit.normal);
                
                int index = hit.triangleIndex * 3;
                
                newMesh.vertices = mesh.vertices;
                newMesh.uv = mesh.uv;
                newMesh.tangents = mesh.tangents;
                newMesh.normals = mesh.normals;
                int[] triangles =mesh.triangles;
                
              
                
                int vertIndex_1 = triangles[hit.triangleIndex * 3 + 0];
                int vertIndex_2 = triangles[hit.triangleIndex * 3 + 1];
                int vertIndex_3 = triangles[hit.triangleIndex * 3 + 2];
              
                
                // Get the vertices for this triangle
                var vert_1 = newMesh.vertices[vertIndex_1];
                var vert_2 = newMesh.vertices[vertIndex_2];
                var vert_3 = newMesh.vertices[vertIndex_3];

              
                // Get the uv for this triangle
                var uv_1 = newMesh.uv[vertIndex_1];
                var uv_2 = newMesh.uv[vertIndex_2];
                var uv_3 = newMesh.uv[vertIndex_3];

                //Get the Normals for this triangle
                var normal_1 = mesh.normals[vertIndex_1];
                var normal_2 = mesh.normals[vertIndex_2];
                var normal_3 = mesh.normals[vertIndex_3];

                //Get Tangents for this triangle
                Vector4 tangent_1 = mesh.tangents[vertIndex_1];
                Vector4 tangent_2 = mesh.tangents[vertIndex_2];
                Vector4 tangent_3 = mesh.tangents[vertIndex_3];



                // Get the positions for the vertices
                var vertPos_1 = newMesh.vertices[vertIndex_1];
                var vertPos_2 = newMesh.vertices[vertIndex_2];
                var vertPos_3 = newMesh.vertices[vertIndex_3];

                

                // Now for all three vertices we first check if any other triangle if using it
                // by simply count how often the indices are used in the triangles list
                var verticesOccur_1 = 0;
                var verticesOccur_2 = 0;
                var verticesOccur_3 = 0;
                
                //for all three vertices of cloth mesh check if any other triangle is using it by simply count how often the indices are used in the triangles list
                

                for (var i = 0; i < triangles.Length; i++)
                {
                    if (triangles[i] == vertIndex_1)
                        verticesOccur_1++;
                    if (triangles[i] == vertIndex_2)
                        verticesOccur_2++;
                    if (triangles[i] == vertIndex_3)
                        verticesOccur_3++;
                }//end for
                // Remove the vertices
                if (verticesOccur_1 == 1)
                    newMesh.vertices[vertIndex_1] = Vector3.zero;
                if (verticesOccur_2 == 1)
                    newMesh.vertices[vertIndex_2] = Vector3.zero;
                if (verticesOccur_3 == 1)
                    newMesh.vertices[vertIndex_3] = Vector3.zero;

                // Remove the uv
                if (verticesOccur_1 == 1)
                    newMesh.uv[vertIndex_1] = Vector2.zero;
                if (verticesOccur_2 == 1)
                    newMesh.uv[vertIndex_2] = Vector2.zero;
                if (verticesOccur_3 == 1)
                    newMesh.uv[vertIndex_3] = Vector2.zero;

                // Remove the normals
                if (verticesOccur_1 == 1)
                    mesh.normals[vertIndex_1] = Vector3.zero;
                if (verticesOccur_2 == 1)
                    mesh.normals[vertIndex_2] = Vector3.zero;
                if (verticesOccur_3 == 1)
                    mesh.normals[vertIndex_3] = Vector3.zero;

                // Remove the tangents
                if (verticesOccur_1 == 1)
                    mesh.tangents[vertIndex_1] = Vector4.zero;
                if (verticesOccur_2 == 1)
                    mesh.tangents[vertIndex_2] = Vector4.zero;
                if (verticesOccur_3 == 1)
                    mesh.tangents[vertIndex_3] = Vector4.zero;
                
                // Find the intersecting triangles by checking if the ray intersects with their vertices
                //var intersectingTriangles = new List<int>();
                for (int i = 0; i < triangles.Length; i += 3)
                {
                    if (triangles[i] == triangles[index] && triangles[i + 1] == triangles[index + 1] && triangles[i + 2] == triangles[index + 2])
                    {
                        triangles[i] = triangles[triangles.Length - 3];
                        triangles[i + 1] = triangles[triangles.Length - 2];
                        triangles[i + 2] = triangles[triangles.Length - 1];
                    }
                }

                newMesh.triangles= triangles;
                skinnedMeshRenderer.sharedMesh = newMesh;

                //update the mesh with the new vertices, uv, normals and tangents
                mesh.vertices = newMesh.vertices;
                mesh.uv = newMesh.uv;
                mesh.tangents = newMesh.tangents;
                mesh.normals =newMesh.normals;
                //update the tirangles
                //newMesh.triangles = triangles;
                 //update the mesh with the new triangles
                mesh.triangles = newMesh.triangles;
                //update the mesh with the new vertices, uv, normals and tangents
                
 
            
            }//end of if
            else
            {

                Debug.Log("No Triangle to remove" + hit.point);
            }//end of if hit.triangleIndex
        }//end of remove triangle
    }//end of class
}//end of class
7vux5j2d

7vux5j2d1#

因为您正在编辑共享网格,所以这可能不是您所期望的:

mesh = skinnedMeshRenderer.sharedMesh;
......
mesh.vertices = newMesh.vertices;

Plane网格是一个内置的网格,所以当Unity重新启动时它会被还原。由于您的代码,这个错误不会每次都发生,但是如果没有布料组件,它有时会发生。
可以在启动时克隆网格:

private void Start()
{
    mesh = Instantiate(skinnedMeshRenderer.sharedMesh);
    skinnedMeshRenderer.sharedMesh = mesh;
}

那么你就不需要newMesh了,现在可以直接编辑mesh了。

相关问题