【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才能通過,所以這些都不是本回合的可行走節點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章