Planning navigation in several frames: time-sliced search

When dealing with large graphs, computing paths can take a lot of time, even halting the game for a couple of seconds. This could ruins its overall experience, to say the least. Luckily enough there are methods to avoid this.

Note

This recipe is built on top of the principle of using coroutines as a method to keep the game running smoothly while finding a path in the background; some knowledge about coroutines is required.

Getting ready

We'll learn how to implement path-finding techniques using coroutines by refactoring the A* algorithm learned previously, but we will handle its signature as a different function.

How to do it...

Even though this recipe is only defining a function, please take into consideration the comments in the code to understand the indentation and code flow more effectively:

  1. Modify the Graph class and add a couple of member variables. One for storing the path and the other to know whether the coroutine has finished:
    public List<Vertex> path;
    public bool isFinished;
  2. Declare the member function:
    public IEnumerator GetPathInFrames(GameObject srcObj, GameObject dstObj, Heuristic h = null)
    {
        //next steps
    }
  3. Include the following member variables at the beginning:
    isFinished = false;
    path = new List<Vertex>();
    if (srcObj == null || dstObj == null)
    {
        path = new List<Vertex>();
        isFinished = true;
        yield break;
    }
  4. Modify the loop to traverse the graph:
    while (frontier.Count != 0)
    {
        // changes over A*
        yield return null;
        //////////////////////////////
        node = frontier.Remove();
  5. Also, include the other path-retrieval validations:
    if (ReferenceEquals(node.vertex, dst))
    {
        // changes over A*
        path = BuildPath(src.id, node.vertex.id, ref previous);
        break;
        //////////////////////////////
    }
  6. Finally, reset the proper values and return control at the end of the function, after closing the main loop:
    isFinished = true;
    yield break;

How it works...

The yield return null statement inside the main loop works as a flag for delivering control to the higher-level functions, thus computing each new loop in each new frame using Unity's internal multi-tasking system.

See also

  • The Finding the best-promising path with A* recipe

For further information about Coroutines and more examples, please refer to the official documentation available online at:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.239.41