Getting a Static Path

This page describes the possible ways for you to set up a Bot with a static Path for it to follow, from the simplest to the most complex.

Basic: using the default A* query

This is the simplest approach to computing new paths, and is typically recommended for initial integrations. For example, if you followed the instructions in the integration tutorial (see Integrating Navigation into your Game Engine), you have already set up a Bot using this method.

In this approach, you simply call Bot::ComputeAStarQueryAsync(), and specify the destination position. The Bot transparently:

Note that if a path computation was already in progress, the previous request is automatically canceled.

For example:

void MyGameEntity::Goto(Kaim::Vec3f destination)
{
    // Clear the followed path
    m_navBot->ClearFollowedPath();

    // Request the new path computation
    m_navBot->ComputeAStarQueryAsync(destination);
}

Advanced: customizing the AStar query on the fly

The approach to path calculation shown above handles the most common path calculation scenarios with a simple API, and is ideal for getting your integration up and running. However, it forces you to use the AStarQuery class with pre-set default behavior. You may eventually find that your project requires you to customize the options and settings offered by the AStarQuery on the fly, or to set up the query in a way that is not exposed in the path finding configuration parameters you can set for the Bot. See also AStarQuery Options.

To explore these possibilities, you can use the "advanced" path calculation API offered by the Bot class. However, doing so requires a little more care.

In this approach:

The Bot requests the query to be launched asynchronously during the next update of the World.

Note that your call to Bot::ComputePathAsync() will fail if a path computation was launched for the Bot in a previous frame, and that previous computation has not yet finished. Before you call Bot::ComputePathAsync(), you should test whether or not a computation is currently running by calling Bot::IsComputingPath(). If this method returns true, you should either skip your new pathfinding request, or cancel the previous request by calling Bot::CancelComputePathAsync().

For example:

class MyGameEntity
{
    void Initialize(Kaim::World* world);
    void Goto(Kaim::Vec3f destination);
    Kaim::Ptr<Kaim::BaseAStarQuery> m_aStarQuery;
};

void MyGameEntity::Initialize(Kaim::World* world)
{
    ...
    // We create and assign the query
    m_aStarQuery = m_navBot->GetFollowedPathNavigationProfile()->CreateAStarQuery();
 
    // Bind the query to the Database used by the Bot
    m_aStarQuery->BindToDatabase(m_navBot->GetDatabase());
 
    // Set up configuration parameters for the query, if desired
    m_aStarQuery->SetTryCanGoMode(Kaim::PATHFINDER_NEVER_TRY_RAYCANGO);
}

void MyGameEntity::Goto(Kaim::Vec3f destination)
{
    if (m_navBot->IsComputingPath())
    {
        m_navBot->CancelComputePathAsync();
    }

    // Clear the followed path
    m_navBot->ClearFollowedPath();

    // Set the inputs of the path finding query
    m_aStarQuery->Initialize(m_navBot->GetPosition(), destination);

    // Adjust other parameters on the fly if necessary
    m_aStarQuery->SetPropagationBoxExtent(200.0f);

    // Request the new path computation
    m_navBot->ComputePathAsync(m_aStarQuery);
}

Advanced: using a different path finding query class

If for some reason the default AStarQuery class does not fit your needs, you can use a different path finding query. For details on the other query classes provided in the SDK, and an overview of how to write your own query, see Alternative Path Finding Queries.

To set up a Bot to use your query, you follow a similar process to the one described in the previous section. However, in this case, you do not retrieve your query from the NavigationProfile, and you have a little more setup to do to ensure that the generated path will be compatible with the Bot's path following system.

The Bot requests the query to be launched asynchronously during the next update of the World.

Note that your call to Bot::ComputePathAsync() will fail if a path computation was launched for the Bot in a previous frame, and that previous computation has not yet finished. Before you call Bot::ComputePathAsync(), you should test whether or not a computation is currently running by calling Bot::IsComputingPath(). If this method returns true, you should either skip your new pathfinding request, or cancel the previous request by calling Bot::CancelComputePathAsync().

Advanced: injecting an existing Path

Sometimes, instead of having a character compute a new path, you may want it to use a path that you have already computed. For example, this could be a Path computed by a different Bot, a Path that you have computed yourself by running a pathfinding query directly, a Path that you have pre-computed and saved in a class member somewhere, or even a Path that you construct on the fly yourself (although this is usually not recommended).

You can instruct a Bot to follow an existing path by passing the Path object in a call to Bot::InjectPath(). For example:

Kaim::Path::CreateConfig myPathCreateConfig;
myPathCreateConfig.m_nodesCount = 2;

Kaim::Ptr<Kaim::Path> myPath = Kaim::Path::CreatePath(myPathCreateConfig);
myPath->SetNodePosition(0, Kaim::Vec3f(0.0f, 0.0f, 0.0f));
myPath->SetNodePosition(1, Kaim::Vec3f(1.0f, 1.0f, 0.0f));
myPath->SetPathEdgeType(0, Kaim::PathEdgeType_OnNavMesh);

m_navBot->InjectPath(myPath);

Note that to ensure that the path following system used by the Bot will be compatible with the settings used to generate the path, each Path maintains the unique ID of a NavigationProfile that must be used to follow that path. As long as a Bot is following an injected path, its path following system will automatically use that NavigationProfile to retrieve any customizable objects that it should use to control path following, such as the TraverseLogic and IPathEventListObserver.

By default, new Path objects that you create from scratch are set up to use the default NavigationProfile maintained by the World. If your new Path has any special requirements on the way it should be followed that require the use of a custom NavigationProfile, you have to set the appropriate profile ID in your Path by calling Path::SetNavigationProfileId().