Unity 脚本自定义Mesh物体形状
今天研究了一下Unity的Mesh和自定义创建一个正方体和圆形。
参考:https://www.youtube.com/watch?v=IYMQ2ErFz0s
http://www.bubuko.com/infodetail-1843291.html
在自定义Mesh本质上就是定义好你需要绘制图形的点vertices,然后根据这些点来画三角形triangles,再定义好uv(主要用来显示贴图)的坐标系就可以了。
就不多说了,其实可以直接先看第一个参考,在第一个参考的理解下去看第二个参考就可以用Mesh画出一个圆形了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 public class BuildMesh : MonoBehaviour 6 { 7 //参考:https://www.youtube.com/watch?v=IYMQ2ErFz0s 8 9 public Vector3 vertLeftTopFront = new Vector3(-1, 1, 1); 10 public Vector3 vertLeftBottomFront = new Vector3(-1, -1, 1); 11 public Vector3 vertLeftTopBack = new Vector3(-1, 1, -1); 12 public Vector3 vertLeftBottomBack = new Vector3(-1, -1, -1); 13 14 public Vector3 vertRightTopFront = new Vector3(1, 1, 1); 15 public Vector3 vertRightBottomFront = new Vector3(1, -1, 1); 16 public Vector3 vertRightTopBack = new Vector3(1, 1, -1); 17 public Vector3 vertRightBottomBack = new Vector3(1, -1, -1); 18 19 private void Start() 20 { 21 GetComponent<MeshFilter>().mesh = CreateCircleMesh(5, 30); 22 } 23 24 void Update() 25 { 26 27 #region vertices definition 28 Vector3[] vertices = new Vector3[] 29 { 30 // front face 31 // 渲染对象自身坐标系 32 vertLeftTopFront, // left top front,0 33 vertRightTopFront, // right top front,1 34 vertLeftBottomFront, // left bottom front,2 35 vertRightBottomFront, // right bottom front,3 36 37 // back face 38 // 假设有一个箱子,把那个面面对你,那个面就是从你右上,左上,右下,左下顺序排列 39 // 排序之后再把他转为渲染对象的本地坐标系 40 // 所以这里第一个坐标4为right top 41 // 其他同理 42 vertRightTopBack, // rigth top back,4 43 vertLeftTopBack, // left top back,5 44 vertRightBottomBack, //right bottom back,6 45 vertLeftBottomBack, // left bottom back,7 46 47 // left face 48 vertLeftTopBack, // left top back,8 49 vertLeftTopFront, // letf top front,9 50 vertLeftBottomBack, // left bottom back,10 51 vertLeftBottomFront, // letf bottom front,11 52 53 // right face 54 vertRightTopFront, // right top front,12 55 vertRightTopBack, // right top back,13 56 vertRightBottomFront, // right bottom front,14 57 vertRightBottomBack, // right bottom back,15 58 59 // top face 60 vertRightTopFront, // right top front,16 61 vertLeftTopFront, // left top front,17 62 vertRightTopBack, // right top back,18 63 vertLeftTopBack, // left top back,19 64 65 // bottom face 66 vertRightBottomBack, // right bottom back,20 67 vertLeftBottomBack, // left bottom back,21 68 vertRightBottomFront, // right bottom front,22 69 vertLeftBottomFront, // left bottom front,23 70 }; 71 #endregion 72 73 74 #region triangles definition 75 int[] triangles = new int[] 76 { 77 // front face 78 0,2,3, // first triangle 79 3,1,0, // second triangle 80 81 // back face 82 4,6,7, // first triangle 83 7,5,4, // second triangle 84 85 // left face 86 8,10,11, // first triangle 87 11,9,8, // second triangle 88 89 // right face 90 12,14,15, // first triangle 91 15,13,12, // second triangle 92 93 // top face 94 16,18,19, // first triangle 95 19,17,16, // second triangle 96 97 // top face 98 20,22,23, // first triangle 99 23,21,20, // second triangle 100 }; 101 102 #endregion 103 104 #region uvs 105 Vector2[] uvs = new Vector2[] 106 { 107 /** 108 * uv 可以理解为贴图的坐标 109 * uv中的每一项和vertices中的每一项都是一一对应的 110 * 原图的左下角uv坐标定为(0,0),原图的右上角的uv坐标定位(1,1), 111 * 原图的其它任何一个位置按照比例都会有一个uv坐标, 112 * 比如原图的左上角的uv坐标定位(0,1),原图的右下角的UV坐标定位(1,0), 113 * 原图的中心(对角线的交点)位置为(0.5,0.5) 114 **/ 115 // front face // 0,0 is bottom left , 1,1 is top right 116 new Vector2(0,1), 117 new Vector2(0,0), 118 new Vector2(1,1), 119 new Vector2(1,0), 120 121 new Vector2(0,1), 122 new Vector2(0,0), 123 new Vector2(1,1), 124 new Vector2(1,0), 125 126 new Vector2(0,1), 127 new Vector2(0,0), 128 new Vector2(1,1), 129 new Vector2(1,0), 130 131 new Vector2(0,1), 132 new Vector2(0,0), 133 new Vector2(1,1), 134 new Vector2(1,0), 135 136 new Vector2(0,1), 137 new Vector2(0,0), 138 new Vector2(1,1), 139 new Vector2(1,0), 140 141 new Vector2(0,1), 142 new Vector2(0,0), 143 new Vector2(1,1), 144 new Vector2(1,0), 145 146 }; 147 #endregion 148 149 Mesh mesh = GetComponent<MeshFilter>().mesh; 150 151 mesh.Clear(); 152 mesh.vertices = vertices; 153 mesh.triangles = triangles; 154 mesh.uv = uvs; 155 mesh.RecalculateNormals(); 156 } 157 158 /// <summary> 159 /// 160 /// </summary> 161 /// <param name="radius">圆的半径</param> 162 /// <param name="segments">分割数</param> 163 public Mesh CreateCircleMesh(float radius, int segments) 164 { 165 // vertices definition 圆形每个点的定义 166 int vertices_count = segments + 1; 167 Vector3[] vertices = new Vector3[vertices_count]; 168 // 圆形的角度范围 169 float angledegree = 360f; 170 // 将角度转换为弧度 171 float angleRad = Mathf.Deg2Rad * angledegree; 172 // 记录当前弧度 173 float angleCur = angleRad; 174 // 每切割一个三角形平均占多少弧度 175 float angledelta = angleRad / segments; 176 177 for (int i = 0; i < vertices_count; i++) 178 { 179 // 角的邻边/斜边 一般用来根据弧度求某相关边的长度 180 float cosA = Mathf.Cos(angleCur); 181 // 角的对边/斜边 182 float sinA = Mathf.Sin(angleCur); 183 184 // radius * cosA根据比例可得到对应的坐标 185 vertices[i] = new Vector3(radius * cosA, 0, radius * sinA); 186 angleCur -= angledelta; 187 } 188 189 // triangles definition 190 int triangle_count = segments * 3; 191 int[] triangles = new int[triangle_count]; 192 for (int i = 0, vi = 1; i <= triangle_count - 1; i += 3, vi++) 193 { 194 triangles[i] = 0; 195 triangles[i + 1] = vi; 196 triangles[i + 2] = vi + 1; 197 } 198 199 triangles[triangle_count - 3] = 0; 200 triangles[triangle_count - 2] = vertices_count - 1; 201 triangles[triangle_count - 1] = 1; 202 203 Vector2[] uvs = new Vector2[vertices_count]; 204 for (int i = 0; i < vertices_count; i++) 205 { 206 uvs[i] = new Vector2(vertices[i].x / radius / 2 + 0.5f, vertices[i].z / radius / 2 + 0.5f); 207 } 208 209 Mesh mesh = new Mesh(); 210 mesh.vertices = vertices; 211 mesh.triangles = triangles; 212 mesh.uv = uvs; 213 mesh.RecalculateNormals(); 214 return mesh; 215 } 216 }