Esempio n. 1
0
    public Vector3 generatePath(Vector3 _position, Vector3 _target, ref List <Vector3> _path)
    {
        int count = 0;

        if (collisionMap.CollisionTable == null)
        {
            return(Vector3.zero);
        }
        // if _target not walkable, re-compute to closer walkable node
        // if _start not walkable something bad happened, break and debug

        // create start node
        int  startX    = (int)_position.x;
        int  startY    = (int)-_position.y;
        Node startNode = new Node(!collisionMap.CheckCollision(startX, startY), startX, startY);

        if (!startNode.walkable)
        {
            Debug.Log("Unwalkable start node.");
            return(Vector3.zero);
        }
        // create target node
        int  targetX    = (int)_target.x;
        int  targetY    = (int)-_target.y;
        Node targetNode = new Node(!collisionMap.CheckCollision(targetX, targetY), targetX, targetY);
        // if target not walkable, consider moving target to closest walkable node

        Heap <Node> openSet   = new Heap <Node>(collisionMap.MapWidth * collisionMap.MapHeight * 10);
        List <Node> closedSet = new List <Node>();

        openSet.Add(startNode);

        // main loop
        while (openSet.Count > 0)
        {
            count++;
            if (count >= breakCount)
            {
                return(Vector3.zero);
            }
            // get node in openSet with lowest fCost
            Node current = openSet.RemoveFirst();
            closedSet.Add(current);

            // check if we found target Node
            if (current.Equals(targetNode))
            {
                Debug.Log("Path found: " + new Vector3(current.x, current.y, 0.0f));
                _path = ReconstructPath(current);
                return(new Vector3(current.x, current.y, 0.0f));
            }

            for (int i = 0; i < dirMap.Length; i++)
            {
                // create new Nodes based on dir and check for collision
                int neighX = current.x + dirMap[i].x;
                int neighY = current.y + dirMap[i].y;

                Node neighbour = new Node(!collisionMap.CheckCollision(neighX, neighY), neighX, neighY);

                if (!neighbour.walkable)
                {
                    continue;
                }

                if (closedSet.Contains(neighbour))
                {
                    continue;
                }

                int tempGScore = current.gCost + 1;
                if (tempGScore < neighbour.gCost || !openSet.Contains(neighbour))
                {
                    neighbour.gCost  = tempGScore;
                    neighbour.hCost  = GetDistance(neighbour, targetNode);
                    neighbour.parent = current;

                    if (!openSet.Contains(neighbour))
                    {
                        openSet.Add(neighbour);
                    }
                    else
                    {
                        openSet.UpdateItem(neighbour);
                    }
                }
            }
        }


        // failed
        Debug.Log("No path found");
        return(Vector3.zero);
    }