战术寻路——避开火力范围
战术寻路我们使用PointGraph来进行控制,这种寻路很适合战术寻路
我们修改A*PathfindingProject的部分源码来实现战术寻路 在Path中我们修改GetTraversalCost函数来实现路径代价的重新计算 源码
代码语言:javascript复制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函数中来判断每一个节点到玩家之间有没有障碍物,以此来进行额外代价的判定。
代码语言:javascript复制//添加代码部分
//玩家对象
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;
//当前处理节点的位置
Vector3 nodePos = (Vector3)node.position;
Vector3 rayStart = nodePos;
rayStart.y = 1.0f;
//玩家位置
Vector3 playerPos = player.transform.position;
Vector3 distance = playerPos - nodePos;
distance.y = 0;
//节点在火力范围内
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函数 源码
代码语言:javascript复制protected void UpdateStartEnd (Vector3 start, Vector3 end) {
originalStartPoint = start;
originalEndPoint = end;
startPoint = start;
endPoint = end;
startIntPoint = (Int3)start;
hTarget = (Int3)end;
}
修改后
代码语言:javascript复制