我已经实施了一个方形移除,以移除两个创建正方形的三角形,它有时会作为一个正方形移除,但问题是它移除的是错误的,而不是被光线投射击中的那个。
代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RemoveSquare : MonoBehaviour
{
[SerializeField] private SkinnedMeshRenderer meshRenderer;
[SerializeField] private Transform selectOrigin;
[SerializeField] [Range(0.1f, 20.0f)] private float maxDistance = 10f;
private Mesh originalMesh;
private Mesh mesh;
private HashSet<int> squaresToRemove = new HashSet<int>();
private void Start()
{
originalMesh = meshRenderer.sharedMesh;
mesh = Instantiate(originalMesh);
}
private void Update()
{
DeleteSquare();
}
private void DeleteSquare()
{
Ray ray = new Ray(selectOrigin.position, selectOrigin.forward);
if (Input.GetKeyDown(KeyCode.C))
{
if (Physics.Raycast(ray, out RaycastHit hit, maxDistance))
{
//Draw a line from object to origin
Debug.DrawLine(selectOrigin.position, hit.point, Color.red, 1f);
// Check if the hit object is the same as this object
if (hit.transform == transform)
{
int[] triangles = mesh.triangles;
int hitTriangleIndex = hit.triangleIndex;
// Add the hit triangle index to the set of triangles to remove
squaresToRemove.Clear();
squaresToRemove.Add(hitTriangleIndex);
// Find the squares that belong to the triangles to remove
foreach (int triangleIndex in new HashSet<int>(squaresToRemove))
{
int[] triangleVertices = new int[3];
triangleVertices[0] = triangles[triangleIndex * 3];
triangleVertices[1] = triangles[triangleIndex * 3 + 1];
triangleVertices[2] = triangles[triangleIndex * 3 + 2];
// Find the triangles that share an edge with the current triangle and add them to the removal list
for (int i = 0; i < triangles.Length / 3; i++)
{
if (i == triangleIndex && IsEdgeShared(triangleVertices, triangleVertices, triangleVertices, triangleVertices))
{
continue;
}
int[] compareVertices = new int[3];
compareVertices[0] = triangles[i * 3];
compareVertices[1] = triangles[i * 3 + 1];
compareVertices[2] = triangles[i * 3 + 2];
int matches = 0;
for (int j = 0; j < 3; j++)
{
if (((IList)triangleVertices).Contains(compareVertices[j]))
{
matches++;
}
}
if (matches == 2)
{
squaresToRemove.Add(i);
break;
}
}
}
// Remove the triangles in the removal list
List<int> newTriangles = new List<int>();
for (int i = 0; i < triangles.Length; i += 3)
{
if (!squaresToRemove.Contains(i / 3))
{
newTriangles.Add(triangles[i]);
newTriangles.Add(triangles[i + 1]);
newTriangles.Add(triangles[i + 2]);
}
}
// Update the mesh triangles and recalculate normals and tangents
mesh.triangles = newTriangles.ToArray();
mesh.RecalculateNormals();
mesh.RecalculateTangents();
meshRenderer.sharedMesh = mesh;
// Show confirmation message
Debug.Log("Squares removed: " + squaresToRemove.Count);
}
}
}
}
// Check if two triangles share an edge and vertex that is only cornered by the two triangles from point a and c to point b and d respectively
private bool IsEdgeShared(int[] a, int[] b, int[] c, int[] d)
{
int matches = 0;
for (int i = 0; i < 3; i++)
{
if (((IList)a).Contains(b[i]))
{
matches++;
}
}
if (matches == 2)
{
return true;
}
matches = 0;
for (int i = 0; i < 3; i++)
{
if (((IList)c).Contains(d[i]))
{
matches++;
}
}
if (matches == 2)
{
return true;
}
return false;
}
}