首页 > 代码库 > Unity 脚本自定义Mesh物体形状

Unity 脚本自定义Mesh物体形状

今天研究了一下Unity的Mesh和自定义创建一个正方体和圆形。

参考:https://www.youtube.com/watch?v=IYMQ2ErFz0s

       http://www.bubuko.com/infodetail-1843291.html

在自定义Mesh本质上就是定义好你需要绘制图形的点vertices,然后根据这些点来画三角形triangles,再定义好uv(主要用来显示贴图)的坐标系就可以了。

就不多说了,其实可以直接先看第一个参考,在第一个参考的理解下去看第二个参考就可以用Mesh画出一个圆形了。

技术分享
  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 }
BuildMesh

 

Unity 脚本自定义Mesh物体形状