2D/3D PathFinder Full | AI | Unity Asset Store
免费:上述是下载地址
当你建构好了各种点和路径后,你可以用pathfinder类来获取各种方法:
首先要using QpathFinder
(如果你在scene有pathfinder脚本,可以直接访问到它)
举例说明:
1.访问从Node1到node10的最小路径
pathfinder.instance.findshortestpathOfnodes(1,10,execution.asynchronously,onpathfond)
其中的OnPathFound是回调函数,表示一旦结果算出后,这个回调函数会被触发。回调函数读取List<Node> nodes
核心算法:
protected IEnumerator FindShortestPathAsynchonousInternal ( int fromNodeID, int toNodeID, System.Action<List<Node>> callback )
{
if ( callback == null )
yield break;
int startPointID = fromNodeID;
int endPointID = toNodeID;
bool found = false;
graphData.ReGenerateIDs();
Node startPoint = graphData.nodesSorted[startPointID];
Node endPoint = graphData.nodesSorted[endPointID];
foreach( var point in graphData.nodes )
{
point.heuristicDistance = -1;
point.previousNode = null;
}
List<Node> completedPoints = new List<Node>();
List<Node> nextPoints = new List<Node>();
List<Node> finalPath = new List<Node>();
startPoint.pathDistance = 0;
startPoint.heuristicDistance = Vector3.Distance ( startPoint.Position, endPoint.Position );
nextPoints.Add( startPoint );
while ( true )
{
Node leastCostPoint = null;
float minCost = 99999;
foreach ( var point in nextPoints )
{
if ( point.heuristicDistance <= 0 )
point.heuristicDistance = Vector3.Distance ( point.Position, endPoint.Position ) + Vector3.Distance( point.Position, startPoint.Position );
if ( minCost > point.combinedHeuristic )
{
leastCostPoint = point;
minCost = point.combinedHeuristic;
}
}
if ( leastCostPoint == null )
break;
if ( leastCostPoint == endPoint )
{
found = true;
Node prevPoint = leastCostPoint;
while ( prevPoint != null )
{
finalPath.Insert(0, prevPoint);
prevPoint = prevPoint.previousNode;
}
if ( QPathFinder.Logger.CanLogInfo )
{
if ( finalPath != null )
{
string str = "";
foreach ( var a in finalPath )
{
str += "=>" + a.autoGeneratedID.ToString();
}
QPathFinder.Logger.LogInfo("Path found between " + fromNodeID + " and " + toNodeID + ":" + str , true );
}
}
callback ( finalPath );
yield break;
}
foreach ( var path in graphData.paths )
{
if ( path.IDOfA == leastCostPoint.autoGeneratedID
|| path.IDOfB == leastCostPoint.autoGeneratedID )
{
if ( path.isOneWay )
{
if ( leastCostPoint.autoGeneratedID == path.IDOfB )
continue;
}
if ( !path.isOpen )
continue;
Node otherPoint = path.IDOfA == leastCostPoint.autoGeneratedID ?
graphData.nodesSorted[path.IDOfB] : graphData.nodesSorted[path.IDOfA];
if ( !otherPoint.IsOpen )
continue;
if ( otherPoint.heuristicDistance <= 0 )
otherPoint.heuristicDistance = Vector3.Distance ( otherPoint.Position, endPoint.Position ) + Vector3.Distance( otherPoint.Position, startPoint.Position );
if ( completedPoints.Contains ( otherPoint) )
continue;
if ( nextPoints.Contains( otherPoint ))
{
if ( otherPoint.pathDistance >
( leastCostPoint.pathDistance + path.cost ) )
{
otherPoint.pathDistance = leastCostPoint.pathDistance + path.cost;
otherPoint.previousNode = leastCostPoint;
}
}
else
{
otherPoint.pathDistance = leastCostPoint.pathDistance + path.cost;
otherPoint.previousNode = leastCostPoint;
nextPoints.Add ( otherPoint );
}
}
}
nextPoints.Remove ( leastCostPoint );
completedPoints.Add ( leastCostPoint );
yield return null;
}
if ( !found )
{
if ( QPathFinder.Logger.CanLogWarning ) QPathFinder.Logger.LogWarning("Path not found between " + fromNodeID + " and " + toNodeID, true );
callback ( null );
yield break;
}
if ( QPathFinder.Logger.CanLogError ) QPathFinder.Logger.LogError("Unknown error while finding the path!", true );
callback ( null );
yield break;
}