Ejemplo n.º 1
0
    // just to check if we can reach our goal from spawning point
    // edge case for spawning point
    // private bool canReachDestination(){
    //     float distance = Vector3.Distance(transform.position, destination.pos);

    //     Vector3 direction = destination.pos - transform.position;
    //     RaycastHit hitInfo;
    //     // currently can walk through air
    //     if (Physics.SphereCast(transform.position, 3.0f, destination.pos, out hitInfo, distance)){
    //         // then we can move directly, we assume we won't collide with other agents
    //         // if we can reach our goal
    //         Debug.Log("CanReachWillReturn " + hitInfo.transform.tag != "Wall" && hitInfo.transform.tag != "Agent" && hitInfo.transform.tag != "LShape");
    //         Debug.Log(hitInfo.transform.tag);
    //         return hitInfo.transform.tag != "Wall" && hitInfo.transform.tag != "Agent" && hitInfo.transform.tag != "LShape";
    //         }
    //         return false;
    //     }

    // This is will look at nearby vertices that are accessible from the agent's current position
    // and return the nearest one
    private PathVertex getNearbyVertex()
    {
        List <PathVertex> allVertices       = VisibilityGraphGenerator.getVertices();
        List <PathVertex> potentialVertices = new List <PathVertex>();

        RaycastHit hitInfo;

        for (int i = 0; i < allVertices.Count; i++)
        {
            Vector3 direction = allVertices[i].pos - transform.position;
            float   distance  = Vector3.Distance(transform.position, allVertices[i].pos);
            if (Physics.SphereCast(transform.position, 3.0f, direction, out hitInfo, distance))
            {
                if (hitInfo.transform.tag != "Wall" && hitInfo.transform.tag != "LShape")
                {
                    potentialVertices.Add(allVertices[i]);
                }
            }
        }
        float min   = float.MaxValue;
        int   index = 0;

        for (int i = 0; i < potentialVertices.Count; i++)
        {
            float dist = Vector3.Distance(transform.position, potentialVertices[i].pos);
            if (dist < min)
            {
                min   = dist;
                index = i;
            }
        }
        return(potentialVertices[index]);
    }
Ejemplo n.º 2
0
    // Runs A* on our graph : f(n) = g(n) + h(n)
    // g(n) : distance from the source
    // h(n) : estimate of the actual cost to get to the destination, it will be calculated from Vector3.Distance()
    // our destination node is added into our graph but it isnt displayed
    // returns the order of nodes that we need to walk through to reach our destination
    public List <PathVertex> pathFind()
    {
        System.DateTime before = System.DateTime.Now;
        System.DateTime after;

        PathVertex startVertex = new PathVertex(start);

        startVertex.gCost = 0.0f; // by definition
        startVertex.fCost = Vector3.Distance(startVertex.pos, destination);
        startVertex.setFCost();
        fringe.Add(startVertex);


        List <PathVertex> pathToTake = new List <PathVertex>();
        // here we set the g cost to ALL our nodes to be infinity and we calculate the fcost
        List <PathVertex> allNodes = VisibilityGraphGenerator.getVertices();

        foreach (PathVertex v in allNodes)
        {
            v.parentVertex = null;
            v.gCost        = float.MaxValue;
            v.setFCost();
        }

        // PSEUDO CODE FROM CLASS (DEAR TA, YOU DON'T NEED TO READ THIS, IT'S JUST FOR LOGIC/DEBUGGING)
        // we might need to see node more than once
        // g(start) = 0
        // f(start) = g(start) + h(start) = h(start)
        // g(n =/= start) = infinity, thus f(n =/= start) = infinity also
        // fringe = {start} we start from the frige
        // we keep going, while (fringe is not empty set):
        // c = find node in the fringe that has the smallest f function (initially its start)
        // if c == destination => done
        // else : look at all neighbours n of C:
        // compute new distance = g(c) + cost(getting from c to n)
        // if dist < g(n) :
        //      if n is not in the fringe and dist + h(n) < f (n) :
        //      add n to the fringe
        //  either way, we're gonna update g(n) = dist
        //  f(n) = g(n) + h(n)
        // our heuristic will be the straight distance to our destination

        // basically f(start) = g(start) + h(start) = h(start) since g(start) = 0
        while (fringe.Count > 0)
        {
            PathVertex current = getVertexWithSmallestFCost(fringe); // returns the one with smallest f function
            if (current.pos == destination)
            {
                // we're done
                after           = System.DateTime.Now;
                pathPlaningTime = after.Subtract(before).Milliseconds;

                return(getPath(current));
            }
            // if current != destination THEN :
            fringe.Remove(current); // we remove bc we've already searched it -> prevent infinite loop
            // exploredVertices.Add(current);

            // now we look at all neighbours of C
            foreach (PathVertex neighbor in VisibilityGraphGenerator.getNeighbors(current))
            {
                // we only want the neighbors that we haven't explored already
                // if (exploredVertices.Contains(neighbor)){
                //     continue;
                // }
                float transitionDistance      = Vector3.Distance(current.pos, neighbor.pos);
                float alternativeBestDistance = current.gCost + transitionDistance;     // g(neighbor)

                // if we found new best distance for neighbor then we update our neighbor
                if (alternativeBestDistance < neighbor.gCost)
                {
                    neighbor.gCost        = alternativeBestDistance;
                    neighbor.parentVertex = current;
                    neighbor.hCost        = Vector3.Distance(current.pos, destination);
                    neighbor.setFCost();
                    // if neighbor isn't in fringe, this just returns false, we don't care
                    // our way of updating the neighbor whether it was in our fringe or not
                    fringe.Remove(neighbor);
                    fringe.Add(neighbor);
                }
            }
        }
        // outside of while -> empty fringe -> couldn't find path -> return null
        // sometimes path is not found, why?
        after           = System.DateTime.Now;
        pathPlaningTime = after.Subtract(before).Milliseconds;
        return(null);
    }