在上篇教程中,我们已经把Map中的每个点都实实在在的画了出来,四个点形成一个正方形。其中,正方形的每条边都有一个中点。
那么,这节课我们来把该连在一起的点连起来,绘制我们的mesh。
public class Square
{
public ControlNode topLeft, topRight, bottomLeft, bottomRight; //一个矩形拥有四个控制节点
public Node centerTop, centerLeft, centerRight, centerBottom; //还有四个节点
public int configuration;
public Square(ControlNode _topLeft, ControlNode _topRight, ControlNode _bottomLeft, ControlNode _bottomRight) //我们只需要定义四个控制节点
{
topLeft = _topLeft;
topRight = _topRight;
bottomLeft = _bottomLeft;
bottomRight = _bottomRight;
//控制节点包含节点
centerTop = topLeft.right;
centerBottom = bottomLeft.right;
centerLeft = bottomLeft.above;
centerRight = bottomRight.above;
if (topLeft.isActive)
configuration += 8;
if (topRight.isActive)
configuration += 4;
if (bottomRight.isActive)
configuration += 2;
if (bottomLeft.isActive)
configuration += 1;
}
}
首先完善一下我们的Square类,增加了一个int变量configuration,我们用它来记录当前矩形控制节点的激活情况,
如果左上激活:对应1000=8,
如果右上激活:对应0100=4;
如果左下激活:对应0010=2;
如果右下激活:对应0001=1;
然后我们定义一个分形函数TriangulateSquare,顾名思义,用来把一个Square分割成三角形。
void TriangulateSquare(Square square)
{
switch (square.configuration)
{
//1 point
case 1:
MeshFromPoints(square.centerBottom, square.bottomLeft, square.centerLeft);
break;
case 2:
MeshFromPoints(square.centerRight, square.bottomRight, square.centerBottom);
break;
case 4:
MeshFromPoints(square.centerTop, square.topRight, square.centerRight);
break;
case 8:
MeshFromPoints(square.topLeft, square.centerTop, square.centerLeft);
break;
//2 points
case 3:
MeshFromPoints(square.centerRight, square.bottomRight, square.bottomLeft, square.centerLeft);
break;
case 6:
MeshFromPoints(square.centerTop, square.topRight, square.bottomRight, square.centerBottom);
break;
case 9:
MeshFromPoints(square.topLeft, square.centerTop, square.centerBottom, square.bottomLeft);
break;
case 12:
MeshFromPoints(square.topLeft, square.topRight, square.centerRight, square.centerLeft);
break;
case 5:
MeshFromPoints(square.centerTop, square.topRight, square.centerRight, square.centerBottom, square.bottomLeft, square.centerLeft);
break;
case 10:
MeshFromPoints(square.topLeft, square.centerTop, square.centerRight, square.bottomRight, square.centerBottom, square.centerLeft);
break;
// 3 point:
case 7:
MeshFromPoints(square.centerTop, square.topRight, square.bottomRight, square.bottomLeft, square.centerLeft);
break;
case 11:
MeshFromPoints(square.topLeft, square.centerTop, square.centerRight, square.bottomRight, square.bottomLeft);
break;
case 13:
MeshFromPoints(square.topLeft, square.topRight, square.centerRight, square.centerBottom, square.bottomLeft);
break;
case 14:
MeshFromPoints(square.topLeft, square.topRight, square.bottomRight, square.centerBottom, square.centerLeft);
break;
// 4 point:
case 15:
MeshFromPoints(square.topLeft, square.topRight, square.bottomRight, square.bottomLeft);
break;
}
}
void MeshFromPoints(params Node[] nodes)
{
AssignVerticals(nodes); //在创建三角形之前,先存储一下它的顶点信息
if (nodes.Length>=3)
{
CreateTriangle(nodes[0], nodes[1], nodes[2]);
}
if (nodes.Length >= 4)
{
CreateTriangle(nodes[0], nodes[2], nodes[3]);
}
if (nodes.Length >= 5)
{
CreateTriangle(nodes[0], nodes[3], nodes[4]);
}
if (nodes.Length >= 6) //如果有6个点,那我们需要创建4个三角形
{
CreateTriangle(nodes[0], nodes[4], nodes[5]);
}
}
void AssignVerticals(Node[] points)
{
for (int i = 0; i < points.Length;i++ )
{
if (points[i].vertexIndex==-1)
{
points[i].vertexIndex = verticals.Count;
verticals.Add(points[i].position);
}
}
}
void CreateTriangle(Node a, Node b, Node c)
{
triangles.Add(a.vertexIndex);
triangles.Add(b.vertexIndex);
triangles.Add(c.vertexIndex);
}
你也许已经注意到了,我们还没有定义verticals和triangles,把它们定义为类的字段:
List<Vector3> verticals;
List<int> triangles;
就快完成了!现在给我们的游戏物体挂上Mesh Filter和Mesh Renderer组件,同时创建一个黑色的Material材质球,挂载到Mesh Renderer组件里的Materail数组中。
接着我们把MeshGenerator中的OnGizmosDraw函数注释掉,已经不需要它啦~
同时修改以下代码:
public void GenerateMesh(int[,] map, int squareSize)
{
squareGrid = new SquareGrid(map, squareSize);
verticals=new List<Vector3>();
triangles=new List<int>();
for (int x = 0; x < squareGrid.squares.GetLength(0); x++)
{
for (int y = 0; y < squareGrid.squares.GetLength(1); y++)
{
TriangulateSquare(squareGrid.squares[x, y]);
}
}
Mesh mesh=new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
mesh.vertices=verticals.ToArray();
mesh.triangles=triangles.ToArray();
mesh.RecalculateNormals();
}
我们使用代码手动定义了一个mesh组件。好,到现在已经完成了,我们来运行看下,希望不会出错:
喔噢!大功告成,简直不能再棒了!