Mesh网格编程 正6面体

首先我们分析下原理:

1.所有模型都是由一个一个三角形面构成。那么我们先来创建一个三角形:

[csharp] view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class example : MonoBehaviour  
  5. {  
  6.     void Start()  
  7.     {  
  8.         gameObject.AddComponent<MeshFilter>();  
  9.         gameObject.AddComponent<MeshRenderer>();  
  10.         Mesh mesh = GetComponent<MeshFilter>().mesh;  
  11.         mesh.Clear();  
  12.         mesh.vertices = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0) };  
  13.         mesh.uv = new Vector2[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1) };  
  14.         mesh.triangles = new int[] { 0, 1, 2 };  
  15.     }  
  16. }  


其中的mesh.trangles就是这个三角形,为什么是3个int类型的数呢?因为trangles是一个包含顶点数组索引的三角形列表。

因此这个数组的的大小必须是3的倍数,顶点可以通过简单的索引同一顶点来共享。

建议先赋值顶点数组后再赋值三角形数组,避免数组越界的错误。

2.上面有了一个三角形的网格创建,现在咱们尝试建一个正方形。

[csharp] view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class example : MonoBehaviour  
  5. {  
  6.     void Start()  
  7.     {  
  8.         gameObject.AddComponent<MeshFilter>();  
  9.         gameObject.AddComponent<MeshRenderer>();  
  10.         Mesh mesh = GetComponent<MeshFilter>().mesh;  
  11.         mesh.Clear();  
  12.         mesh.vertices = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0), new Vector3(1, 0, 0) };  
  13.         mesh.uv = new Vector2[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1) };  
  14.         mesh.triangles = new int[] { 0, 1, 2, 0, 2, 3 };  
  15.     }  
  16. }  
我们发现这个代码,就比三角形多了一个顶点和一个三角形,我们输出图片后就明白三角形为什么这么设置了。

Mesh网格编程 正6面体

两个三角形的顶点,根据三角形的位置来划分。

3.有了前面两个基础了,下面我们来创建一个立方体(六面体)。

好在六面体是一个非常规则的图形,我们可以计算出,每个定点的位置,共8个定点。但是前面提到了,每个三角形被3个定点公用,我们一个顶点坐标需要有3个,分别被3个三角形使用。这样这个三角形的数组设置起来就比较方便了。下面看代码:

[csharp] view plain copy
  1. using UnityEngine;  
  2. using UnityEditor;  
  3.   
  4. public class BoxEditor : Editor  
  5. {  
  6.     static Mesh mesh;            // 网格  
  7.     static Vector3[] Vs;         // 模型顶点坐标数组  
  8.     static int[] Ts;             // 三角形的点序列  
  9.     static float lenght = 1f;  
  10.   
  11.     [MenuItem("GameObject/Create Other/Box")]  
  12.     static void CreateRegular()  
  13.     {  
  14.         lenght /= 2f;  
  15.         //网格定点,8个顶点,每个定点被3个三角形公用,共24个定点  
  16.         Vs = new Vector3[]{  
  17.             new Vector3(lenght, -lenght, lenght),  
  18.             new Vector3(-lenght, -lenght, lenght),  
  19.             new Vector3(lenght, lenght, lenght),  
  20.             new Vector3(-lenght, lenght, lenght),  
  21.             new Vector3(lenght, lenght, -lenght),  
  22.             new Vector3(-lenght, lenght, -lenght),  
  23.             new Vector3(lenght, -lenght, -lenght),  
  24.             new Vector3(-lenght, -lenght, -lenght),  
  25.             new Vector3(lenght, lenght, lenght),  
  26.             new Vector3(-lenght, lenght, lenght),  
  27.             new Vector3(lenght, lenght, -lenght),  
  28.             new Vector3(-lenght, lenght, -lenght),  
  29.             new Vector3(lenght, -lenght, -lenght),  
  30.             new Vector3(lenght, -lenght, lenght),  
  31.             new Vector3(-lenght, -lenght, lenght),  
  32.             new Vector3(-lenght, -lenght, -lenght),  
  33.             new Vector3(-lenght, -lenght, lenght),  
  34.             new Vector3(-lenght, lenght, lenght),  
  35.             new Vector3(-lenght, lenght, -lenght),  
  36.             new Vector3(-lenght, -lenght, -lenght),  
  37.             new Vector3(lenght, -lenght, -lenght),  
  38.             new Vector3(lenght, lenght, -lenght),  
  39.             new Vector3(lenght, lenght, lenght),  
  40.             new Vector3(lenght, -lenght, lenght) };  
  41.   
  42.         //三角形的面,(顶点索引构成,每3个顶点一个面,)  
  43.         Ts = new int[] {   
  44.             0, 2, 3,  
  45.             0, 3, 1,  
  46.             8, 4, 5,  
  47.             8, 5, 9,  
  48.             10, 6, 7,  
  49.             10, 7, 11,  
  50.             12, 13, 14,  
  51.             12, 14, 15,  
  52.             16, 17, 18,  
  53.             16, 18, 19,  
  54.             20, 21, 22,  
  55.             20, 22, 23, };  
  56.           
  57.         // 调用创建对象函数  
  58.         CreateObjectByMesh("Box");  
  59.     }  
  60.   
  61.     // 创建对象函数(这个功能提出来,方便以后扩展)  
  62.     static void CreateObjectByMesh(string name)  
  63.     {  
  64.         GameObject regular = new GameObject();  // 创建游戏对象  
  65.         regular.name = name;                    // 根据参数命名  
  66.         regular.AddComponent<MeshFilter>();     // 添加MeshFilter组件  
  67.         regular.AddComponent<MeshRenderer>();   // 添加MeshRenderer组件  
  68.   
  69.         mesh = new Mesh();                      // 创建网格  
  70.         mesh.vertices = Vs;                     // 网格的顶点  
  71.         mesh.triangles = Ts;                    // 网格的三角形  
  72.         regular.GetComponent<MeshFilter>().mesh = mesh; // 添加网格  
  73.     }  
  74. }  

这是一个编辑器脚本,写完后放到你的Editor文件夹下,然后选择Unity上面的菜单栏,GameObject->Create Other->Box就行了。

然后赋值上材质,如下图所示:

Mesh网格编程 正6面体