首先我们要知道创建mesh需要哪些组件
image.pngMesh Filter:内包含一个Mesh组件,可以根据MeshFilter获得模型网格的组件,也可以为MeshFilter设置Mesh内容。
Mesh Render:是用于把网格渲染出来的组件。MeshFilter的作用就是把Mesh扔给MeshRender将模型或者说是几何体绘制显示出来。
他们的关系是Mesh Filter把模型准备好需要的顶点坐标,法线等属性,Mesh Render才能将此网格渲染出来,不然是看不见该网格的。
mesh的属性
1.顶点坐标(vertex)
2.法线(normal)
3.纹理坐标(uv)
4.三角形序列(triangle)
顶点坐标:顶点坐标数组存放Mesh的每个顶点的空间坐标,假设某mesh有n个顶点,则vertexs的长度为n
法线:法线数组存放mesh每个顶点的法线,normals的长度等于vertexs的长度
纹理坐标:它定义了图片上每个点的位置的信息. 这些点与3D模型是相互联系的, 以决定表面纹理贴图的位置. UV就是将图像上每一个点精确对应到模型物体的表面. uv[i]对应vertex[i]
三角形序列:每个mesh都由若干个三角形组成,而三角形的三个点就是顶点坐标里的点,三角形的triangles长度是三角形个数 * 3.
创建mesh
设置顶点的位置
顶点的位置就是在世界坐标的点
顶点个数:24 (一个面4个顶点,6个面)
-
设置世界坐标时的顺序:
前面的四个点的是0123
那么背面的四个点是4567
(0->4)(1->5)(2->6)(3->7)
(这个顺序是我随便弄的,不是绘制mesh的顺序)
image.png
image.png
设置三角面
三角面个数:36 (一个面的2个三角形,6个面,一个三角形需要三个点)
-
三角面点的循环顺序:
逆时针和顺时针循环的方向会导致面的法线方向不同,而这个法线方向会决定这个面的朝向。
确定使用的顺序,我是试出来的,我就一个半桶水的。
我们要确定使用的这个法线方向其实很简单,Unity里是左手坐标系,拿出左手,伸直,拇指与其他四个指头垂直,然后四指弯曲,指尖朝向循环的方向,拇指就指向法线的方向。
image.png
设置UV
UV点和顶点是意义对应的,一张UV图是二维坐标,坐标:(0,0)到(1,1)
具体的操作我是看https://blog.csdn.net/nanggong/article/details/54969867
代码
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UIElements;
using UnityEngine.Experimental.XR;
public class CreateCube : MonoBehaviour
{
public Material material;
[Header("Z")]
public float length = 1;
[Header("X")]
public float width = 1;
[Header("Y")]
public float heigth = 1;
private int[] triangles;
private Vector2[] uvs;
private Vector3[] vertices;
private int trianglesCount;
private Mesh mesh;
private MeshFilter meshFilter;
void OnEnable()
{
GameObject obj = Create( width, length, heigth, Vector3.zero);
obj.GetComponent<MeshRenderer>().material = material;
}
GameObject Create(float width, float length, float heigth, Vector3 Point)
{
GameObject NewObj = gameObject;//; new GameObject("Cube");
NewObj.name = "Cube";
NewObj.AddComponent<MeshFilter>();
NewObj.AddComponent<MeshRenderer>();
meshFilter = NewObj.GetComponent<MeshFilter>();
int vertices_count = 24;
vertices = new Vector3[vertices_count];
vertices[0] = new Vector3(Point.x - width / 2, Point.y - heigth / 2, Point.z - length / 2);
vertices[1] = new Vector3(Point.x - width / 2, Point.y + heigth / 2, Point.z - length / 2);
vertices[2] = new Vector3(Point.x + width / 2, Point.y - heigth / 2, Point.z - length / 2);
vertices[3] = new Vector3(Point.x + width / 2, Point.y + heigth / 2, Point.z - length / 2);
vertices[4] = new Vector3(Point.x + width / 2, Point.y - heigth / 2, Point.z + length / 2);
vertices[5] = new Vector3(Point.x + width / 2, Point.y + heigth / 2, Point.z + length / 2);
vertices[6] = new Vector3(Point.x - width / 2, Point.y - heigth / 2, Point.z + length / 2);
vertices[7] = new Vector3(Point.x - width / 2, Point.y + heigth / 2, Point.z + length / 2);
vertices[8] = vertices[6]; //左
vertices[9] = vertices[7];
vertices[10] = vertices[0];
vertices[11] = vertices[1];
vertices[12] = vertices[2]; //右
vertices[13] = vertices[3];
vertices[14] = vertices[4];
vertices[15] = vertices[5];
vertices[16] = vertices[1]; //上
vertices[17] = vertices[7];
vertices[18] = vertices[3];
vertices[19] = vertices[5];
vertices[20] = vertices[2]; //下
vertices[21] = vertices[4];
vertices[22] = vertices[0];
vertices[23] = vertices[6];
int SplitTriangle = 6 * 2;
trianglesCount = SplitTriangle * 3;
triangles = new int[trianglesCount];
for (int i = 0, vi = 0; i < trianglesCount; i += 6, vi += 4)
{
triangles[i] = vi;
triangles[i + 1] = vi + 1;
triangles[i + 2] = vi + 2;
triangles[i + 3] = vi + 3;
triangles[i + 4] = vi + 2;
triangles[i + 5] = vi + 1;
}
uvs = new Vector2[vertices.Length];
Vector3[] normals = new Vector3[vertices.Length];
uvs[0] = new Vector2(1 * width, 1 * heigth);
uvs[1] = new Vector2(1 * width, 0);
uvs[2] = new Vector2(0, 1 * heigth);
uvs[3] = new Vector2(0, 0);
uvs[4] = new Vector2(0, 0);
uvs[5] = new Vector2(0, 1 * heigth);
uvs[6] = new Vector2(1 * width, 0);
uvs[7] = new Vector2(1 * width, 1 * heigth);
uvs[8] = new Vector2(0, 0);
uvs[9] = new Vector2(0, 1 * heigth);
uvs[10] = new Vector2(1 * length, 0);
uvs[11] = new Vector2(1 * length, 1 * heigth);
uvs[12] = new Vector2(0, 0);
uvs[13] = new Vector2(0, 1 * heigth);
uvs[14] = new Vector2(1 * length, 0);
uvs[15] = new Vector2(1 * length, 1 * heigth);
uvs[16] = new Vector2(1 * width, 1 * length); //上
uvs[17] = new Vector2(1 * width, 0);
uvs[18] = new Vector2(0, 1 * length);
uvs[19] = new Vector2(0, 0);
uvs[20] = new Vector2(1 * width, 1 * length); //下
uvs[21] = new Vector2(1 * width, 0);
uvs[22] = new Vector2(0, 1 * length);
uvs[23] = new Vector2(0, 0);
mesh = new Mesh();
mesh.name = "cube";
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.normals = normals;
mesh.uv = uvs;
mesh.RecalculateTangents();
mesh.RecalculateNormals();
meshFilter.mesh = mesh;
return NewObj;
}
}
image.gif
参考:
https://www.cnblogs.com/answer-yj/p/11231247.html
https://blog.csdn.net/nanggong/article/details/54969867
网友评论