在以前的內容中咱們已經成功生成了一個面,接下來咱們要生成剩下的面就很容易了。c#
咱們把以前生成的面看成頂面,接着咱們來生成底面。ide
還記得前面說過\(\color{#1E90FF}{Depth}\)這個參數用來控制深度,也就是頂面和地面之間的距離,放到座標系中就是控制Z的位置。優化
底面和頂面的頂點生成方法是同樣的,惟一不一樣的地方就是Z軸的不一樣。 咱們只要用生成頂面的方法改下Z座標,就能夠獲得底面了。ui
//下 for (int i = 0; i <= NumberOfSides; i++) { float angle = 180 - i * incrementAngle; float innerX = (Radius - Thickness) * Mathf.Cos(angle * Mathf.Deg2Rad); float innerY = (Radius - Thickness) * Mathf.Sin(angle * Mathf.Deg2Rad); vertexList.Add(new Vector3(innerX, innerY, -1 * Depth / 2)); float outsideX = Radius * Mathf.Cos(angle * Mathf.Deg2Rad); float outsideY = Radius * Mathf.Sin(angle * Mathf.Deg2Rad); vertexList.Add(new Vector3(outsideX, outsideY, - 1 * Depth / 2)); }
三角形索引的生成和以前也是同樣的,不一樣的是一開始的方向,由於頂面的法線是向上的,而底面的法線是向下的:spa
direction = 1; startIndex += (NumberOfSides + 1) * 2; for (int i = 0; i < NumberOfSides * 2; i++) { int[] triangleIndexs = getTriangleIndexs(i, direction, startIndex); direction *= -1; for (int j = 0; j < triangleIndexs.Length; j++) { triangleList.Add(triangleIndexs[j]); } }
至於UV索引則設置和頂面的同樣便可。code
其餘生成頂面和底面以後,大部分的工做已經完成了,這時候咱們已經生成了咱們須要的全部頂點。先後左右也只是用現有的這些頂點進行生成。orm
咱們前面生成的圓柱體是基於圓生成的,若是咱們改爲基於貝塞爾生成的那也是能夠的。索引
修改方法很簡單,就是改下生成頂點時的過程就行了,其餘的不須要動。rem
具體過程直接看代碼吧,包看包懂。get
固然下面的代碼是爲了方面理解因此寫得冗餘,若是用到項目中建議優化下,否則會被主程打的。
using System.Collections; using System.Collections.Generic; using UnityEngine; //[RequireComponent(typeof(MeshFilter))] //[RequireComponent(typeof(MeshRenderer))] [ExecuteInEditMode] public class DrawArch : MonoBehaviour { public float Radius = 20.0f; //外圈的半徑 public float Thickness = 10.0f; //厚度,外圈半徑減去內圈半徑 public float Depth = 1.0f; //厚度 public int NumberOfSides = 30; //由多少個面組成 public float DrawArchDegrees = 90.0f; //要繪畫多長 public Material archMaterial = null; private int VertexCountOneSide = 0; //生成一面所需的頂點數 private Mesh mesh = null; private float incrementAngle = 0; private List<Vector3> vertexList = new List<Vector3>(); private List<int> triangleList = new List<int>(); private List<Vector2> uvList = new List<Vector2>(); // Start is called before the first frame update void Start() { mesh = new Mesh(); } void GenerateMesh() { VertexCountOneSide = (NumberOfSides + 1) * 2; incrementAngle = DrawArchDegrees / NumberOfSides; GenerateVertex(); GenerateTriangleIndex(); GenerateUV(); mesh.vertices = vertexList.ToArray(); mesh.uv = uvList.ToArray(); mesh.triangles = triangleList.ToArray(); mesh.RecalculateNormals(); gameObject.GetComponent<MeshFilter>().mesh = mesh; gameObject.GetComponent<MeshRenderer>().material = archMaterial; } //生成頂點座標 void GenerateVertex() { //上 vertexList.Clear(); for (int i = 0; i <= NumberOfSides; i++) { float angle = 180 - i * incrementAngle; float innerX = (Radius - Thickness) * Mathf.Cos(angle * Mathf.Deg2Rad); float innerY = (Radius - Thickness) * Mathf.Sin(angle * Mathf.Deg2Rad); vertexList.Add(new Vector3(innerX, innerY, Depth / 2)); float outsideX = Radius * Mathf.Cos(angle * Mathf.Deg2Rad); float outsideY = Radius * Mathf.Sin(angle * Mathf.Deg2Rad); vertexList.Add(new Vector3(outsideX, outsideY, Depth / 2)); } //下 for (int i = 0; i <= NumberOfSides; i++) { float angle = 180 - i * incrementAngle; float innerX = (Radius - Thickness) * Mathf.Cos(angle * Mathf.Deg2Rad); float innerY = (Radius - Thickness) * Mathf.Sin(angle * Mathf.Deg2Rad); vertexList.Add(new Vector3(innerX, innerY, -1 * Depth / 2)); float outsideX = Radius * Mathf.Cos(angle * Mathf.Deg2Rad); float outsideY = Radius * Mathf.Sin(angle * Mathf.Deg2Rad); vertexList.Add(new Vector3(outsideX, outsideY, - 1 * Depth / 2)); } //前 for (int i = 0; i <= NumberOfSides * 2 ; i += 2) { vertexList.Add(vertexList[i]); vertexList.Add(vertexList[i + VertexCountOneSide]); } //後 for (int i = 0; i <= NumberOfSides * 2; i += 2) { vertexList.Add(vertexList[i + 1]); vertexList.Add(vertexList[i + VertexCountOneSide + 1]); } //左 vertexList.Add(vertexList[0]); vertexList.Add(vertexList[1]); vertexList.Add(vertexList[VertexCountOneSide + 0]); vertexList.Add(vertexList[VertexCountOneSide + 1]); //右 vertexList.Add(vertexList[VertexCountOneSide -2]); vertexList.Add(vertexList[VertexCountOneSide - 1]); vertexList.Add(vertexList[VertexCountOneSide * 2 - 2]); vertexList.Add(vertexList[VertexCountOneSide * 2 - 1]); } void GenerateTriangleIndex() { //三角形索引 triangleList.Clear(); //上 int direction = -1; int startIndex = 0; for (int i = 0; i < NumberOfSides * 2; i++) { int[] triangleIndexs = getTriangleIndexs(i, direction); direction *= -1; for (int j = 0; j < triangleIndexs.Length; j++) { triangleList.Add(triangleIndexs[j]); } } //下 direction = 1; startIndex += (NumberOfSides + 1) * 2; for (int i = 0; i < NumberOfSides * 2; i++) { int[] triangleIndexs = getTriangleIndexs(i, direction, startIndex); direction *= -1; for (int j = 0; j < triangleIndexs.Length; j++) { triangleList.Add(triangleIndexs[j]); } } //前 direction = 1; startIndex += VertexCountOneSide; for (int i = 0; i < NumberOfSides * 2; i++) { int[] triangleIndexs = getTriangleIndexs(i, direction, startIndex); direction *= -1; for (int j = 0; j < triangleIndexs.Length; j++) { triangleList.Add(triangleIndexs[j]); } } //後 direction = -1; startIndex += VertexCountOneSide; for (int i = 0; i < NumberOfSides * 2; i++) { int[] triangleIndexs = getTriangleIndexs(i, direction, startIndex); direction *= -1; for (int j = 0; j < triangleIndexs.Length; j++) { triangleList.Add(triangleIndexs[j]); } } startIndex += VertexCountOneSide; //左 triangleList.Add(startIndex + 0); triangleList.Add(startIndex + 1); triangleList.Add(startIndex + 2); triangleList.Add(startIndex + 3); triangleList.Add(startIndex + 2); triangleList.Add(startIndex + 1); //右 triangleList.Add(startIndex + 4 + 2); triangleList.Add(startIndex + 4 + 1); triangleList.Add(startIndex + 4 + 0); triangleList.Add(startIndex + 4 + 1); triangleList.Add(startIndex + 4 + 2); triangleList.Add(startIndex + 4 + 3); } //UV索引 void GenerateUV() { uvList.Clear(); //上 for (int i = 0; i <= NumberOfSides; i++) { float angle = 180 - i * incrementAngle; float littleX = (1.0f / NumberOfSides) * i; uvList.Add(new Vector2(littleX, 0)); float bigX = (1.0f / NumberOfSides) * i; uvList.Add(new Vector2(bigX, 1)); } //下 for (int i = 0; i <= NumberOfSides; i++) { float angle = 180 - i * incrementAngle; float littleX = (1.0f / NumberOfSides) * i; uvList.Add(new Vector2(littleX, 0)); float bigX = (1.0f / NumberOfSides) * i; uvList.Add(new Vector2(bigX, 1)); } //前 for (int i = 0; i <= NumberOfSides; i++) { float angle = 180 - i * incrementAngle; float littleX = (1.0f / NumberOfSides) * i; uvList.Add(new Vector2(littleX, 0)); float bigX = (1.0f / NumberOfSides) * i; uvList.Add(new Vector2(bigX, 1)); } //後 for (int i = 0; i <= NumberOfSides; i++) { float angle = 180 - i * incrementAngle; float littleX = (1.0f / NumberOfSides) * i; uvList.Add(new Vector2(littleX, 0)); float bigX = (1.0f / NumberOfSides) * i; uvList.Add(new Vector2(bigX, 1)); } //左 uvList.Add(new Vector2(1.0f, 1.0f)); uvList.Add(new Vector2(0.0f, 1.0f)); uvList.Add(new Vector2(0.0f, 0.0f)); uvList.Add(new Vector2(1.0f, 0.0f)); //右 uvList.Add(new Vector2(1.0f, 1.0f)); uvList.Add(new Vector2(0.0f, 1.0f)); uvList.Add(new Vector2(0.0f, 0.0f)); uvList.Add(new Vector2(1.0f, 0.0f)); } int[] getTriangleIndexs(int index, int direction, int startIndex = 0) { int[] triangleIndexs = new int[3] { 0+ startIndex, 1 + startIndex, 2 + startIndex }; for (int i = 0; i < triangleIndexs.Length; i++) { triangleIndexs[i] += index; } if (direction == -1) { int temp = triangleIndexs[0]; triangleIndexs[0] = triangleIndexs[2]; triangleIndexs[2] = temp; } return triangleIndexs; } private void Update() { GenerateMesh(); } }