Unity实现A*算法 代码
时间: 2023-06-13 13:03:52 浏览: 46
以下是一个简单的Unity C#脚本来实现A*算法:
```csharp
using UnityEngine;
using System.Collections.Generic;
public class AStar : MonoBehaviour {
public Transform seeker, target; // 寻路的起点和终点
Grid grid; // 存储地图信息的网格
void Awake() {
grid = GetComponent<Grid>();
}
void Update() {
FindPath(seeker.position, target.position);
}
void FindPath(Vector3 startPos, Vector3 targetPos) {
Node startNode = grid.NodeFromWorldPoint(startPos); // 起点所在的网格节点
Node targetNode = grid.NodeFromWorldPoint(targetPos); // 终点所在的网格节点
List<Node> openSet = new List<Node>(); // 未处理的节点集合
HashSet<Node> closedSet = new HashSet<Node>(); // 已处理的节点集合
openSet.Add(startNode); // 将起点加入未处理的节点集合
while (openSet.Count > 0) {
Node currentNode = openSet[0]; // 当前处理的节点
for (int i = 1; i < openSet.Count; i++) {
if (openSet[i].fCost < currentNode.fCost || (openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost)) {
currentNode = openSet[i];
}
}
openSet.Remove(currentNode);
closedSet.Add(currentNode);
if (currentNode == targetNode) { // 已找到终点
RetracePath(startNode, targetNode);
return;
}
foreach (Node neighbor in grid.GetNeighbors(currentNode)) {
if (!neighbor.walkable || closedSet.Contains(neighbor)) {
continue;
}
int newMovementCostToNeighbor = currentNode.gCost + GetDistance(currentNode, neighbor);
if (newMovementCostToNeighbor < neighbor.gCost || !openSet.Contains(neighbor)) {
neighbor.gCost = newMovementCostToNeighbor;
neighbor.hCost = GetDistance(neighbor, targetNode);
neighbor.parent = currentNode;
if (!openSet.Contains(neighbor)) {
openSet.Add(neighbor);
}
}
}
}
}
void RetracePath(Node startNode, Node endNode) {
List<Node> path = new List<Node>();
Node currentNode = endNode;
while (currentNode != startNode) {
path.Add(currentNode);
currentNode = currentNode.parent;
}
path.Reverse();
grid.path = path;
}
int GetDistance(Node nodeA, Node nodeB) {
int dstX = Mathf.Abs(nodeA.gridX - nodeB.gridX);
int dstY = Mathf.Abs(nodeA.gridY - nodeB.gridY);
if (dstX > dstY) {
return 14 * dstY + 10 * (dstX - dstY);
}
else {
return 14 * dstX + 10 * (dstY - dstX);
}
}
}
```
这个脚本依赖于一个名为`Grid`的组件,它存储了地图信息的网格。 `Grid`组件的实现不在本文的讨论范围内,你可以参考其他教程或者使用你自己的实现。
在`Update()`函数中,我们不断地调用`FindPath()`函数来执行A*算法。在`FindPath()`函数中,我们首先找到起点和终点所在的网格节点,然后使用A*算法找到从起点到终点的最短路径。最后,我们使用`RetracePath()`函数来反向遍历路径链表,并将路径保存在`Grid`组件的`path`变量中。