Exemplo n.º 1
0
        /// <summary>
        /// Set the target position of the agent.
        /// </summary>
        public void setTarget(Vector3 target)
        {
            this.target = target;
            target.z    = 0;
            // find the path
            if (TopDown2DNavMeshBaker.navMeshNodes == null)
            {
                TopDown2DNavMeshBaker.init();
            }
            NavMesh2DNode closestStart       = TopDown2DNavMeshBaker.navMeshNodes.findNearestNode(transform.position);
            NavMesh2DNode closestGoal        = TopDown2DNavMeshBaker.navMeshNodes.findNearestNode(target);
            List <IAStarable <Vector3> > map = new List <IAStarable <Vector3> > ();

            for (int i = 0; i < TopDown2DNavMeshBaker.navMeshNodes.nodes.Count; i++)
            {
                IAStarable <Vector3> newNode = (IAStarable <Vector3>)TopDown2DNavMeshBaker.navMeshNodes.nodes [i];
                newNode.heuristicFunction = () => {
                    return(Vector3.Distance(newNode.value, closestGoal.position));
                };
                map.Add(newNode);
            }
            StartCoroutine(AStarAlgorithm.findPath <Vector3> (map, (IAStarable <Vector3>)closestStart, (IAStarable <Vector3>)closestGoal, pathHandler));
        }
Exemplo n.º 2
0
        /// <summary>
        /// A Coroutine function that can be used to find the best path according the heuristic function of the nodes.
        /// Noted that T is the type of the value variable of the node.
        /// </summary>
        public static IEnumerator findPath <T>(List <IAStarable <T> > map, IAStarable <T> start, IAStarable <T> goal, Action <List <IAStarable <T> > > pathHandler)
        {
            // set of nodes already evaluated
            HashSet <IAStarable <T> > closeSet = new HashSet <IAStarable <T> > ();
            // set of nodes currently discovered and not yet evaluated
            HashSet <IAStarable <T> > openSet = new HashSet <IAStarable <T> >();

            // Initially, only the start node is known
            openSet.Add(start);

            // empty list to store the nodes that can be most effeciently reached from
            Dictionary <int, int> cameFrom = new Dictionary <int, int> ();

            // cost of getting from start node to that node
            float[] gScore = new float[map.Count];
            for (int i = 0; i < gScore.Length; i++)
            {
                gScore [i] = float.MaxValue;
            }
            // cost of start node to start node is 0
            gScore [start.id] = 0;

            // total cost of getting from start node to goal node
            float[] fScore = new float[map.Count];
            for (int i = 0; i < fScore.Length; i++)
            {
                fScore [i] = float.MaxValue;
            }
            fScore [start.id] = start.heuristicFunction.Invoke();

            while (openSet.Count > 0)
            {
                IAStarable <T> current;
                float          minFScore = float.MaxValue;
                int            minNodeID = int.MaxValue;
                foreach (IAStarable <T> node in openSet)
                {
                    if (fScore [node.id] < minFScore)
                    {
                        minFScore = fScore [node.id];
                        minNodeID = node.id;
                    }
                }
                current = map.Find(x => x.id == minNodeID);

                if (current == goal)
                {
                    yield return(reconstructPath <T> (map, cameFrom, current, pathHandler));

                    break;
                }
                openSet.Remove(current);
                closeSet.Add(current);

                for (int i = 0; i < current.neighbours.Count; i++)
                {
                    if (closeSet.Contains(map [current.neighbours [i]]))
                    {
                        continue;
                    }
                    if (!openSet.Contains(map [current.neighbours [i]]))
                    {
                        openSet.Add(map [current.neighbours [i]]);
                    }
                    // Score/Distance between current node and neighbour
                    float tentativeGScore = gScore[current.id] + current.cost(map[current.neighbours[i]].value);
                    if (tentativeGScore >= gScore[current.neighbours[i]])
                    {
                        continue;
                    }
                    // record the best path until now
                    cameFrom[current.neighbours[i]] = current.id;
                    gScore [current.neighbours [i]] = tentativeGScore;
                    fScore [current.neighbours [i]] = gScore [current.neighbours [i]] + map [current.neighbours [i]].heuristicFunction.Invoke();
                }
                yield return(null);
            }

            // fail to find a path
            pathHandler(null);
        }
Exemplo n.º 3
0
        private static IEnumerator reconstructPath <T> (List <IAStarable <T> > map, Dictionary <int, int> cameFrom, IAStarable <T> current, Action <List <IAStarable <T> > > pathHandler)
        {
            List <IAStarable <T> > totalPath = new List <IAStarable <T> > ();

            totalPath.Add(current);
            int currentNode = current.id;

            while (cameFrom.ContainsKey(currentNode))
            {
                int tempNode;
                cameFrom.TryGetValue(currentNode, out tempNode);
                currentNode = tempNode;
                totalPath.Insert(0, map [currentNode]);
                yield return(null);
            }
            pathHandler(totalPath);
        }