我在上一篇博客中提到,要实现2d弹坑的功能,代码比较复杂,但是思路其实不难。
简单来说,要实现弹坑功能最关键的部分就是找到顶点的位置,以及连线的顺序。具体可以分为以下几步:
(1)在碰撞点生成一个Mesh来模拟爆炸半径;
(2)获取爆炸半径内的顶点;
(3)将在爆炸范围内的顶点从网格中移除;
(4)根据新的顶点数组绘制网格;
(5)更新网格贴图;
(6)更新网格碰撞器。
下面我们先实现第一步,绘制Mesh
绘制Mesh
Unity对于物体的渲染,是基于三角形网格的。如果我们给定了一个顶点数组(一个Vector3矢量),就可以根据这些顶点的位置来创建三角形面,原则上可以创造出任何我们想要的图形。
为了实现圆形弹坑的效果,我们先来创造一个圆形Mesh,用来模拟爆炸的半径。要画一个圆我们有很多种方法,这里我介绍两种方法,(1)即通过圆心和圆周上的点来画圆;(2)通过圆周上的点画圆。
List<Vector3> vertices = new List<Vector3>(); //这里我们用链表来存储顶点的位置,这样可以不用事先计算数组的容量,
//也可以方便增添删除元素(之后实现弹坑需要频繁的增添删除顶点)。
List<int> triangles = new List<int>();//存储顶点顺序,长度必须是3的整数倍
///这里的pos代表传入的位置,radiu代表要生成的圆半径,verticesCount代表圆周上的顶点数
void CreateSphereMesh(Vector3 pos,float radiu,int verticesCount)
{
vertices.Clear();
triangles.Clear();
GameObject sphereMeshGO = new GameObject();//生成一个新的物体,挂载mesh组件
sphereMeshGO.transform.position = pos;//将这个物体的位置设置为鼠标点击的位置
MeshFilter sphereMeshFilter = sphereMeshGO.AddComponent<MeshFilter>();//给物体添加两个组件
MeshRenderer sphereMeshRenderer = sphereMeshGO.AddComponent<MeshRenderer>();
Vector3 center = Vector3.zero;
vertices.Add(pos);//首先将圆心位置存入,位置为0.
float delta = 360f / verticesCount;
float i =0;
while (i < 360)
{
Vector3 temp = new Vector3(radiu * Mathf.Cos(i*Mathf.Deg2Rad), radiu * Mathf.Sin(i * Mathf.Deg2Rad)