【Unity】 HTFramework框架(二十七)A*寻路

更新日期:2019年12月30日。
Github源码:[点我获取源码]

A*寻路简介

常规的A*寻路算法,目前支持两点间寻路,或只提供起点后根据行走值寻所有可行走节点

使用A*寻路

生成寻路网格

在任意物体上添加AStarGrid脚本,此为A*寻路的核心脚本。
在这里插入图片描述
在这里插入图片描述
AStarGrid属性面板:
1.Evaluation Type:估价算法类型,默认采用AStarManhattan(曼哈顿估价算法)
2.Size:寻路网格尺寸。
3.Node Radius:单个节点半径。
4.Ignore Oblique:寻路计算时,忽略对角节点。
5.Auto Generate:自动生成寻路网格,也就是省略本文的下一步。

也可以在其他位置初始化的时候生成寻路网格。

		private AStarGrid _aStarGrid;
        //生成网格
        _aStarGrid.GenerateGrid();

自定义寻路规则

您可以自定义寻路规则,用来处理每一个寻路网格中的节点,比如标记某个节点为不可行走,提升某个节点的自身估价,当角色妄图走过该节点时,它会付出更多的代价(这主要用于寻可行走节点)。

如下,我们自定义一个规则,将横向(X)第5行的第2列到第8列之间设置为不可行走的障碍

public class AStarTestRule : AStarRule
{
    public override void Apply(AStarNode node)
    {
        if (node.XIndex == 5 && node.YIndex > 2 && node.YIndex < 8)
        {
            node.IsCanWalk = false;
        }
    }
}

两点间寻路

寻路网格生成之后便可以直接寻路,我们调用如下接口寻路:

        /// <summary>
        /// 寻路
        /// </summary>
        /// <param name="startPoint">起点</param>
        /// <param name="endPoint">终点</param>
        /// <param name="rule">搜寻规则</param>
        /// <returns>结果路径</returns>
        public List<AStarNode> Pathfinding(Vector3 startPoint, Vector3 endPoint, AStarRule rule = null)

如下,我们新建一个测试流程,键入代码:

/// <summary>
/// A*流程
/// </summary>
public class AStarProcedure : ProcedureBase
{
    private AStarGrid _aStarGrid;
    private AStarTestRule _rule;
    private Transform _startPoint;
    private Transform _endPoint;

    /// <summary>
    /// 流程初始化
    /// </summary>
    public override void OnInit()
    {
        _aStarGrid = GameObject.Find("AStarGrid").GetComponent<AStarGrid>();
        _rule = new AStarTestRule();
        _startPoint = GameObject.Find("StartPoint").transform;
        _endPoint = GameObject.Find("EndPoint").transform;

        //生成网格
        _aStarGrid.GenerateGrid();
    }
    
    /// <summary>
    /// 流程帧刷新
    /// </summary>
    public override void OnUpdate()
    {
        //按下 空格 寻路
        if (Input.GetKeyDown(KeyCode.Space))
        {
            _aStarGrid.Pathfinding(_startPoint.position, _endPoint.position, _rule);
        }

        //按下 回车 寻可行走节点
        if (Input.GetKeyDown(KeyCode.Return))
        {
            _aStarGrid.WalkableNodefinding(_startPoint.position, 5, _rule);
        }
    }
}

我们运行场景,按下空格寻路:
在这里插入图片描述
图中的两个球形为起点和终点,寻路完成后青色的方块为最终路径,红色的方块为障碍物,不可行走。

寻可行走节点

寻可行走节点的功能可以用于部分横版网格回合制游戏,每一回合,每一个角色根据其行走速度,可以在地图上罗列出所有可以行走的终点。

注意:寻可行走节点的功能理论上应用于将地图划分为标准网格的场景,所以在搜寻时会自动忽略对角网格。

我们重新定义一下寻路规则:

public class AStarTestRule : AStarRule
{
    public override void Apply(AStarNode node)
    {
        if (node.XIndex == 5 && node.YIndex > 2 && node.YIndex < 8)
        {
            //提高节点的估价,在某些游戏中,这类节点往往是高山或者湖泊,玩家想要走过去,自然会花费更大的代价
            node.OCost = 1;
        }
    }
}

开始寻可行走节点:

            //以 _startPoint.position 为起点寻可行走路径,角色的行走速度为10
            _aStarGrid.WalkableNodefinding(_startPoint.position, 10, _rule);

在这里插入图片描述
如上图,红框标记的五个节点为高价值节点,角色在经过这些高价值节点时,会降低自身的行走速度,具体根据该节点的价值而定。

我们将角色行走速度改为3:

            //以 _startPoint.position 为起点寻可行走路径,角色的行走速度为3
            _aStarGrid.WalkableNodefinding(_startPoint.position, 3, _rule);

在这里插入图片描述
可以看到,在经过红框的高价值节点【高山】时,角色行走速度为3的情况下只能穿过【高山】抵达另一边的一个节点,在【高山】上往下行走是不行的,因为高山节点的价值为1(常规节点为0),相当于两个常规节点,角色走过需要花费两倍的代价,也就是说必须要速度4才能通过,所以这些都不是本回合的可行走节点。

猜你喜欢

转载自blog.csdn.net/qq992817263/article/details/103761142
今日推荐