Unity3D中如何最优分组两条曲线顶点生成平面网格三角形?
解决Unity中不等长平行曲线生成平面网格的问题
核心思路
因为两条曲线近乎平行且无交点,我们可以分两步处理,既保证所有顶点都被利用,又避免三角形重叠:
- 处理共同长度段:将两条曲线对应位置的相邻顶点组成四边形,再拆分为两个三角形,让网格贴合曲线的基础形状。
- 处理剩余顶点:如果其中一条曲线更长,将剩余的相邻顶点与另一条曲线的最后一个顶点连接成三角形,补全剩余区域。
关键细节
- 顶点索引管理:先把第一条曲线的所有顶点存入
mesh.vertices,再存入第二条曲线的顶点,这样第二条曲线的顶点索引 = 第一条曲线的顶点总数 + 自身在数组中的索引。 - 三角形 winding 顺序:Unity默认顺时针索引的三角形为正面,代码中保持索引顺序为顺时针,避免背面被剔除。
- 性能优化:用
List<int>动态添加三角形索引,最后转成数组,避免预先分配过大的内存;所有三角形无重叠,减少绘制调用的性能开销。
完整代码示例
using UnityEngine; using System.Collections.Generic; public class CurveMeshGenerator : MonoBehaviour { public List<Vector3> curveA; // 第一条曲线的顶点集合 public List<Vector3> curveB; // 第二条曲线的顶点集合 void Start() { GenerateMesh(); } void GenerateMesh() { Mesh mesh = new Mesh(); GetComponent<MeshFilter>().mesh = mesh; // 合并两条曲线的顶点到同一个数组 List<Vector3> combinedVertices = new List<Vector3>(); combinedVertices.AddRange(curveA); combinedVertices.AddRange(curveB); mesh.vertices = combinedVertices.ToArray(); // 生成三角形索引数组 List<int> triangles = new List<int>(); int countA = curveA.Count; int countB = curveB.Count; // 先处理两条曲线长度重叠的部分 int commonSegments = Mathf.Min(countA, countB) - 1; for (int k = 0; k < commonSegments; k++) { // 拆分四边形为第一个三角形:A[k] → A[k+1] → B[k+1] triangles.Add(k); triangles.Add(k + 1); triangles.Add(countA + k + 1); // 拆分四边形为第二个三角形:A[k] → B[k+1] → B[k] triangles.Add(k); triangles.Add(countA + k + 1); triangles.Add(countA + k); } // 处理长度较长的曲线剩余顶点 if (countA > countB) { int lastBIdx = countA + countB - 1; // 第二条曲线最后一个顶点的索引 for (int k = commonSegments; k < countA - 1; k++) { // 用第一条曲线的相邻顶点和第二条曲线的终点组成三角形 triangles.Add(k); triangles.Add(k + 1); triangles.Add(lastBIdx); } } else if (countB > countA) { int lastAIdx = countA - 1; // 第一条曲线最后一个顶点的索引 for (int k = commonSegments; k < countB - 1; k++) { // 用第一条曲线的终点和第二条曲线的相邻顶点组成三角形 triangles.Add(lastAIdx); triangles.Add(countA + k); triangles.Add(countA + k + 1); } } mesh.triangles = triangles.ToArray(); // 自动计算法线和包围盒(可选,根据需求调整) mesh.RecalculateNormals(); mesh.RecalculateBounds(); } }
补充说明
如果曲线长度差异较大,想要更平滑的过渡效果,可以在较长的曲线上插入线性插值顶点,让两条曲线的顶点数一致,再用标准的四边形拆分法生成网格。另外,如果曲线的走向相反,可能需要调整三角形的索引顺序,保证正面朝向正确。
内容的提问来源于stack exchange,提问作者solidcomer
相关产品推荐
相关产品推荐

