Unity中的算法实现 - 图算法 - 图的遍历 - A*算法

本文介绍了在Unity中使用A*算法实现从起点到终点的路径查找,包括Node类的定义、网格的创建、障碍物检测以及A*搜索过程。
摘要由CSDN通过智能技术生成
using System.Collections.Generic;
using UnityEngine;

public class AStarExample : MonoBehaviour
{
    // 表示一个节点的类
    public class Node
    {
        public int x;
        public int y;
        public bool isObstacle;
        public Node parent;
        public int gCost;
        public int hCost;
        public int fCost { get { return gCost + hCost; } }
    }

    public Transform startTransform;   // 起点的Transform
    public Transform targetTransform;  // 终点的Transform

    public LayerMask obstacleMask;     // 障碍物的LayerMask
    public Vector2 gridSize;           // 网格大小

    private Node[,] grid;              // 表示整个网格的二维数组

    void Start()
    {
        CreateGrid();   // 创建网格
        Node startNode = NodeFromWorldPoint(startTransform.position);     // 获取起点节点
        Node targetNode = NodeFromWorldPoint(targetTransform.position);   // 获取终点节点

        List<Node> path = FindPath(startNode, targetNode);    // 查找路径

        if (path != null)
        {
            foreach (Node node in path)
            {
                Debug.Log("Path Node: (" + node.x + ", " + node.y + ")");
            }
        }
    }

    // 创建网格
    void CreateGrid()
    {
        grid = new Node[Mathf.RoundToInt(gridSize.x), Mathf.RoundToInt(gridSize.y)];

        for (int x = 0; x < gridSize.x; x++)
        {
            for (int y = 0; y < gridSize.y; y++)
            {
                Vector3 worldPoint = new Vector3(x, y, 0);
                // 检查当前位置是否有障碍物
                bool isObstacle = Physics2D.OverlapCircle(worldPoint, 0.1f, obstacleMask) != null;
                // 创建节点并存入grid数组
                grid[x, y] = new Node { x = x, y = y, isObstacle = isObstacle };
            }
        }
    }

    // 查找路径的主要方法
    List<Node> FindPath(Node startNode, Node targetNode)
    {
        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++)
            {
                // 寻找fCost最小的节点
                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)
            {
                return RetracePath(startNode, targetNode);
            }

  

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值