unity感觉不错的dijkstra寻路算法插件(非grid-based,为node-based)

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;
        }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值