1.瓦片设置
public Tile parent;
//设置父节点
public Tile[] connectedTile;
//相连的节点
public float costFromOrigin;
//到起点的代价
public float costToTarget;
//到终点的代价
public float TotalCost
{
get
{
return costFromOrigin + costToTarget;
}
}
//计算总代价
2.寻路方法
public Tile FindPath(Tile origin, Tile target)
{
//建立两个列表用于存储瓦片节点
List<Tile> openSet = new List<Tile>();
//待探索节点列表
List<Tile> closedSet = new List<Tile>();
//已探索节点列表
openSet.Add(origin);
//将起点加入待探索节点列表
origin.costFromOrigin = 0;
//设置代价为0
tileDistance = origin.GetComponent<MeshFilter>().sharedMesh.bounds.extents.z * 2;
//这里是获取瓦片的宽度,该处计算公式是用于计算正六边形的宽度
while (openSet.Count > 0)
//循环待探索节点列表直到列表为空
{
openSet.Sort((x, y) => x.TotalCost.CompareTo(y.TotalCost));
Tile currentTile = openSet[0];
//将待探索列表里的所有节点的总代价从小到大排列,并取代价最小的节点作为临时节点
openSet.Remove(currentTile);
closedSet.Add(currentTile);
//将该临时节点从待探索列表中去除,加入已探索列表中
if (currentTile == target)
//如果临时节点为目标节点则跳出循环
{
return target;
//返回目标点
}
foreach (Tile neighbor in currentTile.connectedTile)
//检索临时节点的所有邻节点
{
if (closedSet.Contains(neighbor))
//如果该节点在已探索列表中则跳过
{
continue;
}
float costToNeighbor = currentTile.costFromOrigin + tileDistance;
//临时节点到邻节点的代价,计算公式为:临时节点到起始点的代价+瓦片宽度距离(即一格)
if (costToNeighbor < neighbor.costFromOrigin || !openSet.Contains(neighbor))
//如果临时节点到邻节点的代价小于邻节点到起始点的代价 或 邻节点不在待探索列表中
{
neighbor.costFromOrigin = costToNeighbor;
//邻节点到起始点的代价更新为临时节点到邻节点的代价
neighbor.costToTarget = Vector3.Distance(target.transform.position, neighbor.transform.position);
//计算邻节点到目标点的代价,邻节点和目标点的距离(是瓦片的整数倍)
neighbor.parent = currentTile;
//设置邻节点的父节点为临时节点(用于路线排序)
if (!openSet.Contains(neighbor))
//如果待探索列表中没有邻节点,将邻节点添加到待探索列表中
{
openSet.Add(neighbor);
}
}
}
}
return null;
}
3.计算路线
private Tile[] MakePath(Tile target, Tile origin)
{
List<Tile> tiles = new List<Tile>();
//新建一个列表用于存储瓦片路径
Tile current = target;
//将目标瓦片设置为临时瓦片
while (current != origin)
//不断检索目标点的父节点直到父节点为起始点
{
tiles.Add(current);
if (current.parent != null)
{
current = current.parent;
}
else
{
break;
}
}
tiles.Add(origin);
//将起始点也加入到列表中
tiles.Reverse();
//将列表反转即为获取一条从起始点到目标点的顺序列表
Tile[] tiles = tiles.ToArray();
//将顺序列表存储到瓦片数组中
return tiles;
}
4.完整项目视频预览
[Unity学习记录]编辑器扩展与A*寻路实现