Mesh網格程式設計(四) 正6面體
阿新 • • 發佈:2019-01-26
前兩期轉載了兩個建立流水體和正12面體的文章,今天一個學生問我怎麼建立一個立方體,我的第一印象,Unity自帶的有一個GameObject.CreatePrimitive(PrimitiveType.Cube);方法。但是顯然現在他是想利用網格程式設計建立一個立方體,而不是這個方法。
首先我們分析下原理:
1.所有模型都是由一個一個三角形面構成。那麼我們先來建立一個三角形:
using UnityEngine; using System.Collections; public class example : MonoBehaviour { void Start() { gameObject.AddComponent<MeshFilter>(); gameObject.AddComponent<MeshRenderer>(); Mesh mesh = GetComponent<MeshFilter>().mesh; mesh.Clear(); mesh.vertices = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0) }; mesh.uv = new Vector2[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1) }; mesh.triangles = new int[] { 0, 1, 2 }; } }
其中的mesh.trangles就是這個三角形,為什麼是3個int型別的數呢?因為trangles是一個包含頂點陣列索引的三角形列表。
因此這個陣列的的大小必須是3的倍數,頂點可以通過簡單的索引同一頂點來共享。
建議先賦值頂點陣列後再賦值三角形陣列,避免陣列越界的錯誤。
2.上面有了一個三角形的網格建立,現在咱們嘗試建一個正方形。
我們發現這個程式碼,就比三角形多了一個頂點和一個三角形,我們輸出圖片後就明白三角形為什麼這麼設定了。using UnityEngine; using System.Collections; public class example : MonoBehaviour { void Start() { gameObject.AddComponent<MeshFilter>(); gameObject.AddComponent<MeshRenderer>(); Mesh mesh = GetComponent<MeshFilter>().mesh; mesh.Clear(); mesh.vertices = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0), new Vector3(1, 0, 0) }; mesh.uv = new Vector2[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1) }; mesh.triangles = new int[] { 0, 1, 2, 0, 2, 3 }; } }
兩個三角形的頂點,根據三角形的位置來劃分。
3.有了前面兩個基礎了,下面我們來建立一個立方體(六面體)。
好在六面體是一個非常規則的圖形,我們可以計算出,每個定點的位置,共8個定點。但是前面提到了,每個三角形被3個定點公用,我們一個頂點座標需要有3個,分別被3個三角形使用。這樣這個三角形的陣列設定起來就比較方便了。下面看程式碼:
using UnityEngine; using UnityEditor; public class BoxEditor : Editor { static Mesh mesh; // 網格 static Vector3[] Vs; // 模型頂點座標陣列 static int[] Ts; // 三角形的點序列 static float lenght = 1f; [MenuItem("GameObject/Create Other/Box")] static void CreateRegular() { lenght /= 2f; //網格定點,8個頂點,每個定點被3個三角形公用,共24個定點 Vs = new Vector3[]{ new Vector3(lenght, -lenght, lenght), new Vector3(-lenght, -lenght, lenght), new Vector3(lenght, lenght, lenght), new Vector3(-lenght, lenght, lenght), new Vector3(lenght, lenght, -lenght), new Vector3(-lenght, lenght, -lenght), new Vector3(lenght, -lenght, -lenght), new Vector3(-lenght, -lenght, -lenght), new Vector3(lenght, lenght, lenght), new Vector3(-lenght, lenght, lenght), new Vector3(lenght, lenght, -lenght), new Vector3(-lenght, lenght, -lenght), new Vector3(lenght, -lenght, -lenght), new Vector3(lenght, -lenght, lenght), new Vector3(-lenght, -lenght, lenght), new Vector3(-lenght, -lenght, -lenght), new Vector3(-lenght, -lenght, lenght), new Vector3(-lenght, lenght, lenght), new Vector3(-lenght, lenght, -lenght), new Vector3(-lenght, -lenght, -lenght), new Vector3(lenght, -lenght, -lenght), new Vector3(lenght, lenght, -lenght), new Vector3(lenght, lenght, lenght), new Vector3(lenght, -lenght, lenght) }; //三角形的面,(頂點索引構成,每3個頂點一個面,) Ts = new int[] { 0, 2, 3, 0, 3, 1, 8, 4, 5, 8, 5, 9, 10, 6, 7, 10, 7, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23, }; // 呼叫建立物件函式 CreateObjectByMesh("Box"); } // 建立物件函式(這個功能提出來,方便以後擴充套件) static void CreateObjectByMesh(string name) { GameObject regular = new GameObject(); // 建立遊戲物件 regular.name = name; // 根據引數命名 regular.AddComponent<MeshFilter>(); // 新增MeshFilter元件 regular.AddComponent<MeshRenderer>(); // 新增MeshRenderer元件 mesh = new Mesh(); // 建立網格 mesh.vertices = Vs; // 網格的頂點 mesh.triangles = Ts; // 網格的三角形 regular.GetComponent<MeshFilter>().mesh = mesh; // 新增網格 } }
這是一個編輯器指令碼,寫完後放到你的Editor資料夾下,然後選擇Unity上面的選單欄,GameObject->Create Other->Box就行了。
然後賦值上材質,如下圖所示: