)
Unity Mesh网格绘制实战从三角形到圆柱体的完整代码解析避坑指南在游戏开发中自定义3D模型的创建往往能带来独特的视觉体验。Unity的Mesh系统为开发者提供了强大的底层控制能力让我们能够通过代码精确构建各种几何形状。本文将带你从最基础的三角形绘制开始逐步深入到复杂圆柱体的构建过程中不仅会解析核心代码逻辑更会分享实际开发中容易踩坑的细节。1. 基础准备与环境搭建在开始Mesh编程之前我们需要理解几个核心组件的关系。Mesh是Unity中描述3D几何形状的基础数据结构它由顶点(vertices)、三角形(triangles)、法线(normals)等元素构成。而MeshFilter负责持有Mesh数据MeshRenderer则负责将这些数据渲染到屏幕上。基础设置步骤在场景中创建空GameObject添加MeshFilter和MeshRenderer组件创建默认材质并赋给MeshRenderer编写脚本挂载到该GameObject上using UnityEngine; using System.Collections.Generic; public class MeshGenerator : MonoBehaviour { private MeshFilter meshFilter; private ListVector3 vertices; private Listint triangles; void Start() { meshFilter GetComponentMeshFilter(); vertices new ListVector3(); triangles new Listint(); GenerateMesh(); } void GenerateMesh() { // 具体生成逻辑将在后续章节填充 } }注意确保场景中有光源否则生成的Mesh将不可见。对于测试目的可以添加一个Directional Light。2. 三角形绘制3D世界的基石所有3D图形本质上都是由三角形构成的因此理解三角形绘制是Mesh编程的第一步。一个三角形需要三个顶点以及定义这些顶点连接顺序的索引。关键实现代码void GenerateTriangle() { vertices.Clear(); triangles.Clear(); // 添加三个顶点 vertices.Add(new Vector3(0, 0, 0)); // 顶点0 vertices.Add(new Vector3(1, 0, 0)); // 顶点1 vertices.Add(new Vector3(0.5f, 1, 0)); // 顶点2 // 定义三角形顺时针方向 triangles.Add(0); triangles.Add(1); triangles.Add(2); // 创建并配置Mesh Mesh mesh new Mesh(); mesh.SetVertices(vertices); mesh.SetTriangles(triangles, 0); mesh.RecalculateNormals(); meshFilter.mesh mesh; }常见问题与解决方案问题现象可能原因解决方法三角形不可见法线方向错误检查顶点顺序Unity使用顺时针缠绕顺序只有线框可见未设置材质确保MeshRenderer有有效材质部分面闪烁深度测试冲突调整摄像机位置或使用双面材质提示在Unity编辑器中选中Mesh对象在Scene视图的Shading Mode中选择Wireframe可以查看网格结构。3. 立方体构建共享顶点的陷阱立方体由6个面组成每个面可以分解为2个三角形。初学者常犯的错误是试图共享所有顶点这会导致法线计算异常使立方体看起来像融合在一起。正确实现方法void GenerateCube() { vertices.Clear(); triangles.Clear(); // 定义8个独立顶点实际需要24个顶点每个面使用独立顶点 Vector3[] tempVertices { // 前面 new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0.5f, 0.5f, 0.5f), new Vector3(-0.5f, 0.5f, 0.5f), // 右面独立顶点 new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, -0.5f), // 继续添加其他面顶点... }; // 添加所有顶点 vertices.AddRange(tempVertices); // 定义三角形索引 int[] tempTriangles { // 前面 0, 1, 2, 0, 2, 3, // 右面 4, 5, 6, 4, 6, 7, // 继续添加其他面... }; triangles.AddRange(tempTriangles); // 创建并配置Mesh Mesh mesh new Mesh(); mesh.SetVertices(vertices); mesh.SetTriangles(triangles, 0); mesh.RecalculateNormals(); meshFilter.mesh mesh; }顶点共享策略对比策略顶点数优点缺点完全共享8内存占用小法线计算异常部分共享14-20平衡性能与效果实现复杂完全不共享24效果完美内存占用大在实际项目中可以根据性能需求选择合适的策略。对于移动平台可能需要折中方案而对于PC平台推荐使用完全不共享顶点的方案以获得最佳视觉效果。4. 圆柱体构建参数化建模实战圆柱体是比立方体更复杂的几何形状它由顶面圆、底面圆和侧面组成。我们需要使用三角函数来计算圆形面上的顶点位置并注意侧面三角形的连接方式。完整实现代码void GenerateCylinder(int segments 16, float height 2f, float radius 0.5f) { vertices.Clear(); triangles.Clear(); // 顶部中心点 vertices.Add(Vector3.up * height * 0.5f); // 顶部圆环顶点 for (int i 0; i segments; i) { float angle i * Mathf.PI * 2f / segments; vertices.Add(new Vector3( Mathf.Cos(angle) * radius, height * 0.5f, Mathf.Sin(angle) * radius )); } // 底部中心点 vertices.Add(Vector3.up * height * -0.5f); // 底部圆环顶点 for (int i 0; i segments; i) { float angle i * Mathf.PI * 2f / segments; vertices.Add(new Vector3( Mathf.Cos(angle) * radius, height * -0.5f, Mathf.Sin(angle) * radius )); } // 顶部圆面三角形 for (int i 1; i segments; i) { triangles.Add(0); // 顶部中心 triangles.Add(i); triangles.Add(i % segments 1); } // 底部圆面三角形注意顶点顺序反转 int bottomCenter segments 1; for (int i bottomCenter 1; i bottomCenter segments; i) { triangles.Add(bottomCenter); triangles.Add(i % (bottomCenter segments) 1); triangles.Add(i); } // 侧面三角形 int sideStart bottomCenter segments 1; for (int i 1; i segments; i) { int top i; int bottom bottomCenter i; int nextTop i % segments 1; int nextBottom bottomCenter (i % segments 1); // 第一个三角形 triangles.Add(top); triangles.Add(bottom); triangles.Add(nextTop); // 第二个三角形 triangles.Add(bottom); triangles.Add(nextBottom); triangles.Add(nextTop); } // 创建并配置Mesh Mesh mesh new Mesh(); mesh.SetVertices(vertices); mesh.SetTriangles(triangles, 0); mesh.RecalculateNormals(); mesh.RecalculateBounds(); meshFilter.mesh mesh; }参数优化建议segments控制圆柱体的圆滑程度值越大越圆滑但性能开销越大。通常16-32是合理范围。height/radius可以动态调整圆柱体的比例创建不同形状的柱体。UV坐标如需贴图需要额外计算UV坐标本文为简化未包含这部分代码。在实现圆柱体时特别要注意侧面三角形的连接顺序错误的顺序会导致法线方向异常出现内部可见或外部不可见的问题。调试时可以使用Unity的Scene视图旋转观察确保从各个角度都能正确显示。