我已经实现了移除三角形来移除选中的三角形,使用光线投射。我的实现可以很好地处理网格,因为网格没有布料的组件,但是当我添加布料组件时,我仍然可以移除三角形,但是有一个问题。它会移除三角形,当我停止游戏并重新运行它时,它正确地向我显示了结果,三角形的移除仍然可见,除非我重新启动统一。
我已经分享了几个截图,从开始到结束一步一步沿着代码。
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
1条答案
按热度按时间7vux5j2d1#
因为您正在编辑共享网格,所以这可能不是您所期望的:
Plane
网格是一个内置的网格,所以当Unity重新启动时它会被还原。由于您的代码,这个错误不会每次都发生,但是如果没有布料组件,它有时会发生。可以在启动时克隆网格:
那么你就不需要
newMesh
了,现在可以直接编辑mesh
了。