戰(zhàn)術尋路——避開火力范圍
戰(zhàn)術尋路我們使用PointGraph來進行控制,這種尋路很適合戰(zhàn)術尋路
我們修改A*PathfindingProject的部分源碼來實現戰(zhàn)術尋路
在Path中我們修改GetTraversalCost函數來實現路徑代價的重新計算
源碼
internal uint GetTraversalCost (GraphNode node) {
#if ASTAR_NO_TRAVERSAL_COST
return 0;
#else
// Use traversal provider if set, otherwise fall back on default behaviour
if (traversalProvider != null)
return traversalProvider.GetTraversalCost(this, node);
unchecked { return GetTagPenalty((int)node.Tag) + node.Penalty; }
#endif
}
修改后
在Path class中添加了4個變量
在GetTraversalCost函數中來判斷每一個節(jié)點到玩家之間有沒有障礙物,以此來進行額外代價的判定。
//添加代碼部分
//玩家對象
protected GameObject player;
//玩家火力范圍
protected float fireRange;
//火力范圍的平方
protected float sqrFireRange;
//危險路點的額外代價
protected int penaltyAmount;
internal uint GetTraversalCost (GraphNode node) {
#if ASTAR_NO_TRAVERSAL_COST
return 0;
#else
// Use traversal provider if set, otherwise fall back on default behaviour
if (traversalProvider != null)
return traversalProvider.GetTraversalCost(this, node);
//修改部分
node.Penalty = 0;
//當前處理節(jié)點的位置
Vector3 nodePos = (Vector3)node.position;
Vector3 rayStart = nodePos;
rayStart.y = 1.0f;
//玩家位置
Vector3 playerPos = player.transform.position;
Vector3 distance = playerPos - nodePos;
distance.y = 0;
//節(jié)點在火力范圍內
if(distance.sqrMagnitude < sqrFireRange)
{
//判斷是否有遮擋
RaycastHit hit;
if(Physics.Raycast(nodePos,distance,out hit))
{
//沒有遮擋 路徑懲罰值加上一個額外代價
if(hit.collider.tag == "Player")
{
node.Penalty += (uint)penaltyAmount;
Debug.Log(node.Penalty);
}
}
}
unchecked { return GetTagPenalty((int)node.Tag) + node.Penalty; }
#endif
}
修改ABPath中的UpdateStarEnd函數
源碼
protected void UpdateStartEnd (Vector3 start, Vector3 end) {
originalStartPoint = start;
originalEndPoint = end;
startPoint = start;
endPoint = end;
startIntPoint = (Int3)start;
hTarget = (Int3)end;
}
修改后