unity 基于网格的寻路运动
时间: 2025-02-22 07:02:00 浏览: 37
### Unity 中基于网格的寻路运动实现
#### 创建网格环境
为了在 Unity 中创建一个基本的 2D 正方形网格用于 A* 寻路,首先需要定义网格结构。这可以通过编写脚本来完成。
```csharp
using UnityEngine;
public class Grid : MonoBehaviour {
public int width = 10;
public int height = 10;
private Node[,] grid;
void Start() {
CreateGrid();
}
void CreateGrid() {
grid = new Node[width, height];
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
grid[x, y] = new Node(x, y);
}
}
}
}
```
此代码片段展示了如何初始化并填充节点数组 `grid`,其中每个元素代表网格上的单个位置[^1]。
#### 定义节点属性
对于每一个可能成为路径一部分的位置来说,都需要记录其坐标以及一些辅助数据以便执行 A* 算法:
```csharp
[System.Serializable]
public struct Node {
public bool walkable;
public Vector2 position;
public float gCost;
public float hCost;
public Node parent;
public Node(bool _walkable, Vector2 _position) {
walkable = _walkable;
position = _position;
gCost = 0f;
hCost = 0f;
parent = null;
}
}
```
上述代码中包含了两个成本变量 (`gCost`, `hCost`) 和指向父级节点的引用 `parent`,这些都是标准 A* 实现的一部分[^3]。
#### 计算代价函数
当评估潜在路线时,会涉及到计算从当前节点到达目标所需的成本。通常情况下,这是通过累加水平/垂直移动(每步增加 10)和斜向移动(每步增加 14)的距离来完成的:
```csharp
private static readonly Dictionary<Vector2Int, int> movementPenalties = new Dictionary<Vector2Int, int>() {
{new Vector2Int(1, 0), 10}, // Right
{new Vector2Int(-1, 0), 10},// Left
{new Vector2Int(0, 1), 10}, // Up
{new Vector2Int(0, -1), 10},// Down
{new Vector2Int(1, 1), 14}, // Diagonal up-right
{new Vector2Int(-1, 1), 14},// Diagonal up-left
{new Vector2Int(1, -1), 14},// Diagonal down-right
{new Vector2Int(-1, -1), 14}// Diagonal down-left
};
```
这些数值被用来更新相邻节点之间的相对开销。
#### 执行A*搜索过程
最后一步就是按照经典的 A* 流程迭代处理开放列表直至找到解决方案或确认无解为止。这部分逻辑较为复杂,因此仅给出简化版框架供参考:
```csharp
List<Node> openSet = new List<Node>();
HashSet<Node> closedSet = new HashSet<Node>();
openSet.Add(startNode);
while(openSet.Count > 0){
var currentNode = GetLowestFCostNodeFromOpenSet();
if(currentNode == endNode){
return ReconstructPath(endNode);
}
openSet.Remove(currentNode);
closedSet.Add(currentNode);
foreach(var neighbor in GetNeighborsOfCurrentNode()){
if(!neighbor.walkable || closedSet.Contains(neighbor)){
continue;
}
var tentativeGScore = currentNode.gCost + CalculateDistanceBetweenNodes(currentNode, neighbor);
if (!openSet.Contains(neighbor)) {
openSet.Add(neighbor);
} else if(tentativeGScore >= neighbor.gCost){
continue;
}
neighbor.parent = currentNode;
neighbor.gCost = tentativeGScore;
neighbor.hCost = HeuristicEstimateToGoal(neighbor.position, endPosition);
}
}
return null; // No path found.
```
这段伪代码描述了一个完整的 A* 循环流程,包括获取具有最低 F 成本的节点、检查是否达到目的地、扩展邻居节点等功能[^2]。
阅读全文
相关推荐

















