# Unity3D 打造3D Astar寻路系统详解

Astar算法是一种常用的寻路算法，它通过将地图网格化并使用启发式搜索来找到最短路径。在Unity3D中，我们可以通过编写脚本来实现Astar寻路系统。下面我们将详细介绍如何实现这一功能。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Node
{
public Vector3 position;
public Node parent;
public float gCost;
public float hCost;
public float fCost
{
get { return gCost + hCost; }
}

public Node(Vector3 _pos)
{
position = _pos;
}
}

public class Astar : MonoBehaviour
{
public Transform startNode;
public Transform endNode;

private List<Node> openList = new List<Node>();
private List<Node> closedList = new List<Node>();

private void Start()
{
FindPath(startNode.position, endNode.position);
}

private void FindPath(Vector3 startPos, Vector3 targetPos)
{
Node startNode = new Node(startPos);
Node targetNode = new Node(targetPos);

while (openList.Count > 0)
{
Node currentNode = openList[0];

for (int i = 1; i < openList.Count; i++)
{
if (openList[i].fCost < currentNode.fCost || openList[i].fCost == currentNode.fCost && openList[i].hCost < currentNode.hCost)
{
currentNode = openList[i];
}
}

openList.Remove(currentNode);

if (currentNode == targetNode)
{
RetracePath(startNode, targetNode);
return;
}

foreach (Node neighbour in GetNeighbours(currentNode))
{
if (!closedList.Contains(neighbour))
{
float newCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour);
if (newCostToNeighbour < neighbour.gCost || !openList.Contains(neighbour))
{
neighbour.gCost = newCostToNeighbour;
neighbour.hCost = GetDistance(neighbour, targetNode);
neighbour.parent = currentNode;

if (!openList.Contains(neighbour))
{
}
}
}
}
}
}

private List<Node> GetNeighbours(Node node)
{
List<Node> neighbours = new List<Node>();

Vector3[] directions = new Vector3[]
{
new Vector3(1, 0, 0),
new Vector3(-1, 0, 0),
new Vector3(0, 1, 0),
new Vector3(0, -1, 0),
new Vector3(1, 1, 0),
new Vector3(-1, -1, 0),
new Vector3(1, -1, 0),
new Vector3(-1, 1, 0)
};

foreach (Vector3 dir in directions)
{
Vector3 neighbourPos = node.position + dir * nodeRadius;
{
}
}

return neighbours;
}

private void RetracePath(Node startNode, Node endNode)
{
List<Node> path = new List<Node>();
Node currentNode = endNode;

while (currentNode != startNode)
{
currentNode = currentNode.parent;
}

path.Reverse();

foreach (Node node in path)
{
Debug.Log(node.position);
}
}

private float GetDistance(Node nodeA, Node nodeB)
{
float dstX = Mathf.Abs(nodeA.position.x - nodeB.position.x);
float dstY = Mathf.Abs(nodeA.position.y - nodeB.position.y);
float dstZ = Mathf.Abs(nodeA.position.z - nodeB.position.z);

if (dstX > dstY)
{
return 14 * dstY + 10 * (dstX - dstY) + 10 * dstZ;
}
return 14 * dstX + 10 * (dstY - dstX) + 10 * dstZ;
}
}

• 3
点赞
• 5
收藏
觉得还不错? 一键收藏
• 0
评论
06-19 894
06-13 388

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。