最近工作上用到了Mesh这个组件,需要用这个组件画图,拿十字架练手。
需要用到的组件,Mesh ,MeshRender,MeshFilter。
首先我们了解一下三者的关系,MeshFilter从Mesh拿到需要画图的数据,然后给MeshRender进行渲染。
unity中的图片都是一个个三角形拼接起来的。所以不管是绘制什么,都需要三个点(存在Mesh的vertices中),并且这三个点需要按照逆时针顺序给Mesh的triangles(int的数组,存放需要绘制点的顺序)。
所以如果我们想画一个长方形,其实就是花了两个直角三角形拼接在一起。
如图所示:
接下来我们只需要知道图中四个点的位置即可。
假设中心点是(0,0,0);
那么左下角的点就是(0 - length / 2, 0 - width / 2, 0); 第0个点
左上角的点就是(0 - length / 2, 0 + width / 2, 0); 第1个点
右上角的点就是(0 + length / 2, 0 + width / 2, 0); 第2个点
右下角的点就是(0 + length / 2, 0 - width / 2, 0); 第3个点
所以第一个三角形的逆时针顺序是 0,1,2
第二个三角形的逆时针顺序是 2,3,0
接下来我们将这些数据写入到代码中。
创建一个十字架类
class Cross
{
public Cross()
{
}
public Cross(float length,float width)
{
this.length = length;
this.width = width;
}
public Vector3[] Vertices
{
get { return vertices; }
}
private Vector3[] vertices;
public int[] Triangles
{
get { return triangles; }
}
private int[] triangles;
private float width;
private float length;
public void Init()
{
length = 10;
width = 2;
}
//可以在构造函数的时候就设定长宽,也可以额外写方法设置
public void Init()
{
length = 10;
width = 2;
}
}
然后写一个计算的方法,这里可以写一个算法对数据进行归类,个人这里比较懒,而且可能遇到不同情况,所以就木有写,摸鱼了。
public void ReCal()
{
vertices = new Vector3[8];
//十字架横着的部分
vertices[0] = new Vector3(0 - length / 2, 0 - width / 2, 0);
vertices[1] = new Vector3(0 - length / 2, 0 + width / 2, 0);
vertices[2] = new Vector3(0 + length / 2, 0 + width / 2, 0);
vertices[3] = new Vector3(0 + length / 2, 0 - width / 2, 0);
//十字架竖着的部分
vertices[4] = new Vector3(0 - width / 2, 0 - length / 2, 0);
vertices[5] = new Vector3(0 - width / 2, 0 + length / 2, 0);
vertices[6] = new Vector3(0 + width / 2, 0 + length / 2, 0);
vertices[7] = new Vector3(0 + width / 2, 0 - length / 2, 0);
//绘图点的顺序
triangles = new int[12];
triangles[0] = 0;
triangles[1] = 1;
triangles[2] = 2;
triangles[3] = 2;
triangles[4] = 3;
triangles[5] = 0;
triangles[6] = 4;
triangles[7] = 5;
triangles[8] = 6;
triangles[9] = 6;
triangles[10] = 7;
triangles[11] = 4;
}
十字架类已经完成,此时可以通过方法调用这个类,获取到vertices和triangles传给Mesh。
新建一个脚本作为调用端。
public class Scripts : MonoBehaviour {
void Start () {
Cross cross = new Cross();
cross.Init();
cross.ReCal();
//加载预制件
//var crossPrefab = Resources.Load("Prefab/Cross",typeof(GameObject));
//var Obj = Instantiate(crossPrefab) as GameObject;
//Obj.name = "Test";
//MeshFilter meshFilter = Obj.GetComponent<MeshFilter>();
//临时创建Mesh
MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>();
MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();
Mesh mesh = new Mesh();
mesh.vertices = cross.Vertices;
mesh.triangles = cross.Triangles;
meshFilter.mesh = mesh;
}
}
挂在物体上即可运行。此时一个十字架就画好啦。
效果图:
2D的Demo
到此处只是停留在2D的范围,如果想3D效果显示,那么该怎么做呢?
此时我们需要绘制六个面,依旧是按照顺时针的方向绘制。
3DDemo
ps:这里是u3d萌新一只,不时分享一些工作中遇到的问题