[Chips]Unity开发笔记--代码实现A*寻路

1.瓦片设置

public Tile parent;
//设置父节点
public Tile[] connectedTile; 
//相连的节点
public float costFromOrigin;
//到起点的代价
public float costToTarget;
//到终点的代价
public float TotalCost
    {
        get
        {
            return costFromOrigin + costToTarget;
        }
    }
//计算总代价

2.寻路方法

public Tile FindPath(Tile origin, Tile target)
    {
        //建立两个列表用于存储瓦片节点
        List<Tile> openSet = new List<Tile>(); 
        //待探索节点列表
        List<Tile> closedSet = new List<Tile>(); 
        //已探索节点列表

        openSet.Add(origin);
        //将起点加入待探索节点列表
        origin.costFromOrigin = 0;
        //设置代价为0

        tileDistance = origin.GetComponent<MeshFilter>().sharedMesh.bounds.extents.z * 2;
        //这里是获取瓦片的宽度,该处计算公式是用于计算正六边形的宽度

        while (openSet.Count > 0)
        //循环待探索节点列表直到列表为空
        {
            openSet.Sort((x, y) => x.TotalCost.CompareTo(y.TotalCost));
            Tile currentTile = openSet[0];
            //将待探索列表里的所有节点的总代价从小到大排列,并取代价最小的节点作为临时节点

            openSet.Remove(currentTile);
            closedSet.Add(currentTile);
            //将该临时节点从待探索列表中去除,加入已探索列表中

            if (currentTile == target)
            //如果临时节点为目标节点则跳出循环
            {
                return target;
                //返回目标点
            }

            foreach (Tile neighbor in currentTile.connectedTile)
            //检索临时节点的所有邻节点
            {
                if (closedSet.Contains(neighbor))
                //如果该节点在已探索列表中则跳过
                {
                    continue;
                }

                float costToNeighbor = currentTile.costFromOrigin + tileDistance;
                //临时节点到邻节点的代价,计算公式为:临时节点到起始点的代价+瓦片宽度距离(即一格)
                if (costToNeighbor < neighbor.costFromOrigin || !openSet.Contains(neighbor))
                //如果临时节点到邻节点的代价小于邻节点到起始点的代价 或 邻节点不在待探索列表中
                {
                    neighbor.costFromOrigin = costToNeighbor;
                    //邻节点到起始点的代价更新为临时节点到邻节点的代价
                    neighbor.costToTarget = Vector3.Distance(target.transform.position, neighbor.transform.position);
                    //计算邻节点到目标点的代价,邻节点和目标点的距离(是瓦片的整数倍)
                    neighbor.parent = currentTile;
                    //设置邻节点的父节点为临时节点(用于路线排序)
                    if (!openSet.Contains(neighbor))
                    //如果待探索列表中没有邻节点,将邻节点添加到待探索列表中
                    {
                        openSet.Add(neighbor);
                    }
                }
            }
        }
        return null;
    }

3.计算路线

private Tile[] MakePath(Tile target, Tile origin)
    {
        List<Tile> tiles = new List<Tile>();
        //新建一个列表用于存储瓦片路径
        Tile current = target;
        //将目标瓦片设置为临时瓦片

        while (current != origin)
        //不断检索目标点的父节点直到父节点为起始点
        {
            tiles.Add(current);
            if (current.parent != null)
            {
                current = current.parent;
            }
            else
            {
                break;
            }
        }
        
        tiles.Add(origin);
        //将起始点也加入到列表中
        tiles.Reverse();
        //将列表反转即为获取一条从起始点到目标点的顺序列表

        Tile[] tiles = tiles.ToArray();
        //将顺序列表存储到瓦片数组中
        return tiles;
    }

4.完整项目视频预览

[Unity学习记录]编辑器扩展与A*寻路实现

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值