1. 程式人生 > 實用技巧 >Unity Mesh 網格繪製多邊形

Unity Mesh 網格繪製多邊形

 利用 Mesh 網格在理論上可以繪製出各種形狀,而原理就是所有圖形都是由三角形構成的

 

一、繪製三角形

 1     // 繪製的材質
 2     public Material material;
 3 
 4     void DrawTriangle()
 5     {
 6         // 新增 MeshFilter 和 MeshRenderer 元件
 7         gameObject.AddComponent<MeshFilter>();
 8         gameObject.AddComponent<MeshRenderer>();
9 10 // 繪製圖案的材質 11 gameObject.GetComponent<MeshRenderer>().material = material; 12 13 Mesh mesh = GetComponent<MeshFilter>().mesh; 14 mesh.Clear(); 15 16 // 設定頂點 17 mesh.vertices = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1
, 1, 0) }; 18 19 // 設定三角形頂點順序,順時針設定 20 mesh.triangles = new int[] { 0, 1, 2 }; 21 }
  • 新增元件:MeshFilter 和 MeshRenderer 元件是繪製 Mesh 網格必須的

  • 指定頂點:比如三角形,需要指定三個頂點

  • 指定頂點順序:triangles 陣列的大小必須是3的倍數,頂點的順序必須是順時針(逆時針只能在反面才能看到)

 繪製完成的圖形:

 

二、繪製正方形

 1     // 繪製的材質
 2     public Material material;
3 4 void Start() 5 { 6 DrawSquare(); 7 } 8 9 void DrawSquare() 10 { 11 // 新增 MeshFilter 和 MeshRenderer 元件 12 gameObject.AddComponent<MeshFilter>(); 13 gameObject.AddComponent<MeshRenderer>(); 14 15 // 繪製圖案的材質 16 gameObject.GetComponent<MeshRenderer>().material = material; 17 18 Mesh mesh = GetComponent<MeshFilter>().mesh; 19 mesh.Clear(); 20 21 // 設定頂點 22 mesh.vertices = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0), new Vector3(1, 0, 0) }; 23 mesh.triangles = new int[] { 0, 1, 2, 0, 2, 3 }; 24 }

 繪製兩個三角形就可以組成正方形,所以只要在三角形的基礎上再加一個點(1,0)就可以了

 繪製完成的圖形:

 

三、繪製圓形

 1     // 繪製的材質
 2     public Material material;
 3 
 4     void Start()
 5     {
 6         DrawCircle(3, 50, Vector3.zero);
 7     }
 8 
 9     /// <summary>
10     /// 畫圓
11     /// </summary>
12     /// <param name="radius"> 圓的半徑 </param>
13     /// <param name="segments"> 圓的分割數 </param>
14     /// <param name="centerCircle"> 圓心的位置 </param>
15     void DrawCircle(float radius, int segments, Vector3 centerCircle)
16     {
17         gameObject.AddComponent<MeshFilter>();
18         gameObject.AddComponent<MeshRenderer>();
19         gameObject.GetComponent<MeshRenderer>().material = material;
20 
21         // 計算所需頂點
22         Vector3[] vertices = new Vector3[segments + 1];
23         vertices[0] = centerCircle;
24         float deltaAngle = Mathf.Deg2Rad * 360f / segments;
25         float currentAngle = 0;
26         for (int i = 1; i < vertices.Length; i++)
27         {
28             float cosA = Mathf.Cos(currentAngle);
29             float sinA = Mathf.Sin(currentAngle);
30             vertices[i] = new Vector3(cosA * radius + centerCircle.x, sinA * radius + centerCircle.y, 0);
31             currentAngle += deltaAngle;
32         }
33 
34         // 繪製所需三角形
35         int[] triangles = new int[segments * 3];
36         for (int i = 0, j = 1; i < segments * 3 - 3; i += 3, j++)
37         {
38             triangles[i] = 0;
39             triangles[i + 1] = j + 1;
40             triangles[i + 2] = j;
41         }
42         triangles[segments * 3 - 3] = 0;
43         triangles[segments * 3 - 2] = 1;
44         triangles[segments * 3 - 1] = segments;
45 
46         Mesh mesh = GetComponent<MeshFilter>().mesh;
47         mesh.Clear();
48 
49         mesh.vertices = vertices;
50         mesh.triangles = triangles;
51     }

 繪製圓形的函式需要的引數:半徑、圓心座標以及分割的個數(即組成的三角形個數)

 在相同大小的情況下,分割數越多,所繪製的圓越圓滑

 如下圖,分別是分割數 10 和分割數 50 繪製出來的圓形

四、繪製圓環

 1     // 繪製的材質
 2     public Material material;
 3 
 4     void Start()
 5     {
 6         DrawRing(3, 2, 50, Vector3.zero);
 7     }
 8 
 9     /// <summary>
10     /// 畫圓環
11     /// </summary>
12     /// <param name="radius"> 圓半徑 </param>
13     /// <param name="innerRadius"> 內圓半徑 </param>
14     /// <param name="segments"> 圓的分個數 </param>
15     /// <param name="centerCircle"> 圓心座標 </param>
16     void DrawRing(float radius, float innerRadius, int segments, Vector3 centerCircle)
17     {
18         gameObject.AddComponent<MeshFilter>();
19         gameObject.AddComponent<MeshRenderer>();
20         gameObject.GetComponent<MeshRenderer>().material = material;
21 
22         // 所需頂點
23         Vector3[] vertices = new Vector3[segments * 2];
24         float deltaAngle = Mathf.Deg2Rad * 360f / segments;
25         float currentAngle = 0;
26         for (int i = 0; i < vertices.Length; i += 2)
27         {
28             float cosA = Mathf.Cos(currentAngle);
29             float sinA = Mathf.Sin(currentAngle);
30             vertices[i] = new Vector3(cosA * innerRadius + centerCircle.x, sinA * innerRadius + centerCircle.y, 0);
31             vertices[i + 1] = new Vector3(cosA * radius + centerCircle.x, sinA * radius + centerCircle.y, 0);
32             currentAngle += deltaAngle;
33         }
34 
35         // 所需三角形
36         int[] triangles = new int[segments * 6];
37         for (int i = 0, j = 0; i < segments * 6; i += 6, j += 2)
38         {
39             triangles[i] = j;
40             triangles[i + 1] = (j + 3) % vertices.Length;
41             triangles[i + 2] = (j + 1) % vertices.Length;
42 
43             triangles[i + 3] = j;
44             triangles[i + 4] = (j + 2) % vertices.Length;
45             triangles[i + 5] = (j + 3) % vertices.Length;
46         }
47 
48         Mesh mesh = GetComponent<MeshFilter>().mesh;
49         mesh.Clear();
50 
51         mesh.vertices = vertices;
52         mesh.triangles = triangles;
53     }

 圓環也是在圓形的基礎上,由三角形構成梯形,再由梯形按分割陣列成圓環

 而這裡比圓形多了一個引數:內圓半徑,通過兩個圓的大小去指定圓環的大小

 同樣,在相同大小的情況下,分割數越多,所繪製的圓環越圓滑

 如下圖,分別是分割數 10 和分割數 50 繪製出來的圓環

 

 而繪製其他多邊形也是同樣的原理:

 先確定多邊形的各個頂點,然後按照頂點的順序繪製所需要三角形,最後由繪製的三角形構成所要繪製的多邊形

*** | 以上內容僅為學習參考、學習筆記使用 | ***