一、如何生成Mesh网格
1.分配vertices(网格顶点)
2.分配triangles(三角形数据)
以绘制一个三角形为例:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreatTriangle : MonoBehaviour
{
Vector3[] newVertices;//顶点数组
Vector2[] newUV;
int[] newTriangles;//三角形信息数组
void Start()
{
newVertices = new Vector3[3] { Vector3.zero, Vector3.up, Vector3.right };
newTriangles = new int[3] { 0, 1, 2 };
Mesh mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
mesh.vertices = newVertices;
mesh.uv = newUV;
mesh.triangles = newTriangles;
}
}
新建一个空对象,挂载脚本并添加组件:
二、生成立方体
1.分配矩形的8个顶点
2.按顺序填写三角形信息
代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreatCube : MonoBehaviour
{
public Vector3[] vectors;
List<int> triangs;
Vector2[] uvs;
void Start()
{
uvs = new Vector2[vectors.Length];
Mesh mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
mesh.vertices = vectors;
triangs = new List<int>
{
0,3,1,
1,3,2,
1,2,5,
5,2,6,
4,5,6,
4,6,7,
0,4,7,
0,7,3,
2,3,7,
2,7,6,
5,4,0,
5,0,1
};
mesh.triangles = triangs.ToArray();
mesh.RecalculateNormals();
for (int i = 0; i < uvs.Length; i++)
{
uvs[i] = new Vector2(vectors[i].x, vectors[i].z);
}
mesh.uv = uvs;
}
}
为了方便可以在unity侧分配点:
注意点的顺序改变,相应三角形信息也要做对应改变
三、生成一个反向的球体
因为三角形顺序(顺时针和逆时针)不同,生成网格的朝向也不同,现在利用这个性质生成一个反向的球体
1.利用三角函数计算球体需要的顶点信息
2.计算三角形顺序
代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreatSphere : MonoBehaviour
{
Mesh mesh;
Vector3[] vertices;
Vector2[] uv;
int[] triangles;
Vector3[] normals;
void Start()
{
mesh = new Mesh();
int m = 20; //row
int n = 40; //col
float width = 4;
float height = 3;
int r = 3;
vertices = new Vector3[(m + 1) * (n + 1)];
uv = new Vector2[(m + 1) * (n + 1)];
normals = new Vector3[(m + 1) * (n + 1)];
triangles = new int[6 * m * n];
for (int i = 0; i < vertices.Length; i++)
{
float x = i % (n + 1);
float y = i / (n + 1);
float x_pos = x / n * width;
float y_pos = y / m * height;
vertices[i] = new Vector3(x_pos, y_pos, 0);
float u = x / n;
float v = y / m;
uv[i] = new Vector2(u, v);
}
for (int i = 0; i < 2 * m * n; i++)
{
int[] triIndex = new int[3];
if (i % 2 == 0)
{
triIndex[0] = i / 2 + i / (2 * n);
triIndex[1] = triIndex[0] + 1;
triIndex[2] = triIndex[0] + (n + 1);
}
else
{
triIndex[0] = (i + 1) / 2 + i / (2 * n);
triIndex[1] = triIndex[0] + (n + 1);
triIndex[2] = triIndex[1] - 1;
}
triangles[i * 3] = triIndex[0];
triangles[i * 3 + 1] = triIndex[2];
triangles[i * 3 + 2] = triIndex[1];
}
for (int i = 0; i < vertices.Length; i++)
{
Vector3 v;
v.x = r * Mathf.Cos(vertices[i].x / width * 2 * Mathf.PI) * Mathf.Cos(vertices[i].y / height * Mathf.PI - Mathf.PI / 2);
v.y = r * Mathf.Sin(vertices[i].x / width * 2 * Mathf.PI) * Mathf.Cos(vertices[i].y / height * Mathf.PI - Mathf.PI / 2);
v.z = r * Mathf.Sin(vertices[i].y / height * Mathf.PI - Mathf.PI / 2);
vertices[i] = v;
normals[i] = new Vector3(0, 1, 0);
}
mesh.vertices = vertices;
mesh.normals = normals;
mesh.uv = uv;
mesh.triangles = triangles;
GetComponent<MeshFilter>().mesh = mesh;
GetComponent<MeshCollider>().sharedMesh = mesh;
for (int i = 0; i < 5; i++)
{
GameObject go = Instantiate(Resources.Load<GameObject>("Small"));
}
}
}
通过添加碰撞器和刚体可以实现让小球放在生成的大球内: