最近看到一个游戏 Mini Motorways,研究了一下其中的路径拖拽效果。
思路:通过路径点生成Mesh。
在这里首先想到拖拽,我们就可以得到一系列点,点连成线,线在这里是有弧度的。所以需要曲线函数,在这里二次贝塞尔函数就适用。下面为实现中用的贝塞尔:
public List<Vector3> T2Bezier(Vector3 pos1, Vector3 pos2, Vector3 pos3, int num)
{
List<Vector3> points = new List<Vector3>();
float temp = 1f / num;
//使用3个顶点定义一条曲线。
for (int i = 0; i <= num; i++)
{
float t = temp * i;
float p1 = Mathf.Pow(1 - t, 2);
float p2 = 2 * t * (1 - t);
float p3 = t * t;
Vector3 ans = pos1 * p1 + pos2 * p2 + pos3 * p3;
points.Add(ans);
}
return points;
}
再通过得到的线,往垂直切线的方向上去增加点,得到有宽度的路的顶点坐标。下面为加点函数:
public void DealMeshVer(ref List<Vector3> vertex, float width)
{
List<Vector3> temp = new List<Vector3>();
float offset = width / 2;
for (int i = 1; i < vertex.Count; i++)
{
Vector3 dir = vertex[i] - vertex[i - 1];
if (vertex[i] == vertex[i - 1])
continue;
Vector3 cdir = Vector3.Cross(dir.normalized, Vector3.forward);
temp.Add(vertex[i - 1] + cdir * offset);
temp.Add(vertex[i - 1] - cdir * offset);
if (i == vertex.Count - 1)
{
temp.Add(vertex[i] + cdir * offset);
temp.Add(vertex[i] - cdir * offset);
}
}
vertex = temp;
}
接下来就是设置UVList和TriangleList。这里没有什么特别,就不附代码。
这样就够了一条简单路径的表现。
但是对于游戏中,路径不是只会被一次拖拽。而且有8个方向的变化,List的结构已经不够用。
大致思路,设计格子数据结构,在这里记录它的8个方向的连接情况,当生成路径时,对每个格子的情况单独一个一个处理生成Mesh数据,最后做一个数据上的Mesh合并操作。
最终效果: