版本:unity 5.4.1 语言:C#
最近在看MC的代码,但是10M的代码看得我实在够呛,后来去找了一些Unity相关实现的工程,可惜国内都使用的是cube来做方块,渲染一万个方块还好,百万级别的就够呛了。
后来看了网友的建议后,翻墙去youtube上找了相关的视频,花了一个晚上把代码抄下来后,这几天把核心的渲染逻辑研究清楚了,给大家分享一下。
这边只是做一个面的渲染,一个方块的话就是6个面嘛,都一样的。
上代码:
public class BlockTest : MonoBehaviour {
List<Vector3> vertices = new List<Vector3>();
List<int> triangles = new List<int>();
List<Vector2> uvs = new List<Vector2>();
void Start ()
{
block1();
}
// 显示在y轴上方
void block1()
{
MeshFilter filter = GetComponent<MeshFilter>();
// 顶点,观察点要顺时针绕才能看的见
Vector3 v1 = new Vector3(-0.5f, 0.5f, -0.5f);
Vector3 v2 = new Vector3(-0.5f, 0.5f, 0.5f);
Vector3 v3 = new Vector3(0.5f, 0.5f, 0.5f);
Vector3 v4 = new Vector3(0.5f, 0.5f, -0.5f);
vertices.Add(v1);
vertices.Add(v2);
vertices.Add(v3);
vertices.Add(v4);
// 三角网格
triangles.Add(0);
triangles.Add(1);
triangles.Add(2);
triangles.Add(0);
triangles.Add(2);
triangles.Add(3);
// 贴图UV,这个是贴图的比例
uvs.Add(new Vector2(0.333f, 0));
uvs.Add(new Vector2(0.333f, 0.333f));
uvs.Add(new Vector2(0.666f, 0.333f));
uvs.Add(new Vector2(0.666f, 0));
// 渲染参数设定
filter.mesh.Clear();
filter.mesh.subMeshCount = 1; //贴图数量只设定为一张
filter.mesh.vertices = vertices.ToArray(); //设置顶点信息
filter.mesh.SetTriangles(triangles.ToArray(), 0); //设置三角网格
filter.mesh.uv = uvs.ToArray(); //设置uv,贴图对应的顶点
// 开始重新渲染
filter.mesh.RecalculateNormals();
}
// 显示在y轴下方
void block2()
{
MeshFilter filter = GetComponent<MeshFilter>();
// 顶点
Vector3 v1 = new Vector3(-0.5f, 0.5f, -0.5f);
Vector3 v2 = new Vector3(0.5f, 0.5f, -0.5f);
Vector3 v3 = new Vector3(0.5f, 0.5f, 0.5f);
Vector3 v4 = new Vector3(-0.5f, 0.5f, 0.5f);
vertices.Add(v1);
vertices.Add(v2);
vertices.Add(v3);
vertices.Add(v4);
// 三角网格
triangles.Add(0);
triangles.Add(1);
triangles.Add(2);
triangles.Add(0);
triangles.Add(2);
triangles.Add(3);
// 贴图UV
uvs.Add(new Vector2(0.333f, 0));
uvs.Add(new Vector2(0.666f, 0));
uvs.Add(new Vector2(0.666f, 0.333f));
uvs.Add(new Vector2(0.333f, 0.333f));
filter.mesh.Clear();
filter.mesh.subMeshCount = 1;
filter.mesh.vertices = vertices.ToArray();
filter.mesh.SetTriangles(triangles.ToArray(), 0);
filter.mesh.uv = uvs.ToArray();
filter.mesh.RecalculateNormals();
}
// 这个是错误的
void block3()
{
MeshFilter filter = GetComponent<MeshFilter>();
// 顶点
Vector3 v1 = new Vector3(-0.5f, 0.5f, -0.5f);
Vector3 v2 = new Vector3(0.5f, 0.5f, -0.5f);
Vector3 v3 = new Vector3(-0.5f, 0.5f, 0.5f);
Vector3 v4 = new Vector3(0.5f, 0.5f, 0.5f);
vertices.Add(v1);
vertices.Add(v2);
vertices.Add(v3);
vertices.Add(v4);
// 三角网格
triangles.Add(0);
triangles.Add(1);
triangles.Add(2);
triangles.Add(1);
triangles.Add(2);
triangles.Add(3);
// 贴图UV
uvs.Add(new Vector2(0.333f, 0));
uvs.Add(new Vector2(0.666f, 0));
uvs.Add(new Vector2(0.333f, 0.333f));
uvs.Add(new Vector2(0.666f, 0.333f));
filter.mesh.Clear();
filter.mesh.subMeshCount = 1;
filter.mesh.vertices = vertices.ToArray();
filter.mesh.SetTriangles(triangles.ToArray(), 0);
filter.mesh.uv = uvs.ToArray();
filter.mesh.RecalculateNormals();
}
}
渲染六个面后的效果:
或者这样:
当然单纯一个方块渲染6个面是没有办法提升性能的,我们需要做的是把方块的面选择性加载才能达到优化的效果。