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