在以前的内容中咱们已经成功生成了一个面,接下来咱们要生成剩下的面就很容易了。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(); } }