unity战棋游戏的a*算法代码实现,带注释
时间: 2024-10-17 15:10:48 浏览: 43
在Unity中实现A*(Asterix Star)路径寻路算法,通常用于战棋游戏中角色的移动,可以按照以下步骤编写,并附带一些关键代码段及注释:
```csharp
using UnityEngine;
using System.Collections.Generic;
// 定义AStar类
public class AStar : MonoBehaviour
{
// 节点的数据结构
public struct Node
{
public Vector3 position; // 节点位置
public float gScore; // 从起点到该节点的实际代价
public float hScore; // 到目标的估算代价
public bool isClosed; // 是否已访问过
public Node previousNode; // 上一个节点引用
}
// 关键成员变量
private List<Node> openList = new List<Node>(); // 开放列表
private List<Node> closedList = new List<Node>(); // 封闭列表
// 游戏地图网格大小
private int gridSize;
// 搜索函数
public List<Vector3> FindPath(Vector3 start, Vector3 end)
{
// 初始化
Node startNode = new Node { position = start, gScore = 0, hScore = Heuristic(start, end), isClosed = false };
Node goalNode = new Node { position = end, gScore = Mathf.Infinity, hScore = 0, isClosed = false };
// 将起始节点添加到开放列表
openList.Add(startNode);
while (openList.Count > 0)
{
// 获取当前步法成本最小的节点
Node currentNode = GetLowestFScore(openList);
// 如果找到终点,则回溯并返回路径
if (currentNode.position == goalNode.position)
return ReconstructPath(currentNode);
// 将当前节点从开放列表移除并加入关闭列表
openList.Remove(currentNode);
closedList.Add(currentNode);
// 遍历邻居节点
foreach (Vector3 neighbor in GetNeighbors(currentNode.position))
{
Node neighborNode = GetNode(neighbor);
// 如果邻居未访问过
if (!closedList.Contains(neighborNode) && !openList.Contains(neighborNode))
{
// 计算新的gScore
float tentativeGScore = currentNode.gScore + Distance(currentNode.position, neighbor);
// 如果通过这个路径能到达邻居节点,更新它的gScore
if (tentativeGScore < neighborNode.gScore)
{
neighborNode.previousNode = currentNode;
neighborNode.gScore = tentativeGScore;
neighborNode.hScore = Heuristic(neighborNode.position, end);
neighborNode.isClosed = true;
// 如果邻居节点不在开放列表中,将其加入
if (!openList.Contains(neighborNode))
openList.Add(neighborNode);
}
}
}
}
// 如果找不到路径,返回空列表
return null;
}
// 其他辅助方法
private Node GetNode(Vector3 position)
{
// 在实际项目中,这应该根据地图网格来获取对应位置的节点
// 这里仅作为示例,假设节点位置直接可用
return nodes[(int)position.x, (int)position.y];
}
private List<Vector3> GetNeighbors(Vector3 position)
{
// 根据地图规则获取周围可走的位置
// 这里仅列出示例,实际应用需要考虑碰撞检测和地图边界等
List<Vector3> neighbors = new List<Vector3>();
neighbors.Add(position + new Vector3(-1, 0)); // 左边
neighbors.Add(position + new Vector3(+1, 0)); // 右边
neighbors.Add(position + new Vector3(0, -1)); // 下方
neighbors.Add(position + new Vector3(0, +1)); // 上方
return neighbors;
}
// 计算两点间的曼哈顿距离,简化计算
private float Distance(Vector3 a, Vector3 b)
{
return Mathf.Abs(a.x - b.x) + Mathf.Abs(a.y - b.y);
}
// 估算H值,这里简单采用曼哈顿距离
private float Heuristic(Vector3 pos1, Vector3 pos2)
{
return Distance(pos1, pos2);
}
// 重构路径,从终点开始逆向遍历
private List<Vector3> ReconstructPath(Node current)
{
List<Vector3> path = new List<Vector3>();
path.Add(current.position);
while (current.previousNode != null)
{
current = current.previousNode;
path.Add(current.position);
}
path.Reverse();
return path;
}
// 获取F分值最低的节点
private Node GetLowestFScore(List<Node> list)
{
Node lowestFScoreNode = list[0];
for (int i = 1; i < list.Count; i++)
{
if (list[i].fScore < lowestFScoreNode.fScore)
lowestFScoreNode = list[i];
}
return lowestFScoreNode;
}
}
// 注释:
// - `GetLowestFScore` 函数用于获取开放列表中最优的节点,fScore是gScore加hScore的总和。
// - `Heuristic` 函数可根据场景自定义,这里假设简单的曼哈顿距离。
// - `ReconstructPath` 返回从终点到起点的完整路径。
```
阅读全文