集成阶段 3:加载和卸载 NavData

既然您的地形具有一些 NavData,您需要在游戏中加载相应地形时添加一些代码以将 NavData 加载到数据库,并在不再需要时将其从数据库中移除。

要将 NavData 添加到数据库,您必须:

  1. 将数据从 .NavData 文件读取到内存中。在本示例中,我们将使用 Gameware Navigation SDK 随附的默认文件 opener 对象。
  2. 创建 NavData 类的实例,并为其设置指向数据的指针。
  3. 通过调用 NavData::AddToDatabaseImmediate()NavData::AddToDatabaseAsync() 方法,向数据库提供 NavData 对象。

在本教程的后面,当您将 NavData 生成集成到关卡设计工具时,可以改为将 NavData 集成到用于其他资源的相同数据加载管线,并使用 NavData::LoadFromMemory() 从加载 NavData 的内存位置设置 NavData 实例。请参见集成阶段 6:使用 NavData 生成 API

[Tutorial_FirstIntegration.cpp 中的代码]

#include "gwnavruntime/navdata/navdata.h"
#include "gwnavruntime/kernel/SF_File.h"
#include "gwnavruntime/base/fileopener.h"
...

class MyGameLevel
{
public:
    ...
    bool Initialize(Kaim::World* world);
    ...
    void Destroy();
    ...
protected:
    Kaim::Ptr<Kaim::NavData> m_navData;
    ...
};

bool MyGameLevel::Initialize(Kaim::World* world)
{
    Kaim::Ptr<Kaim::File>   kaimFile;
    Kaim::DefaultFileOpener fileOpener;

    // Open the NavData file.
    const std::string navdataFilePath = TestSystem::Instance().InputDir() + "GeneratedNavData/opencastle/opencastle.NavData";
    kaimFile = fileOpener.OpenFile(navdataFilePath.c_str(), Kaim::OpenMode_Read);
    if(kaimFile == KY_NULL)
        return false;

    // Instantiate and load the NavData from the file contents.
    m_navData = *KY_NEW Kaim::NavData;
    KyResult loadingResult = KY_ERROR;
    loadingResult = m_navData->Load(kaimFile); 

    // Close the NavData file.
    kaimFile ->Close();
    kaimFile = KY_NULL;

    // Check that the NavData have been correctly loaded.
    if (KY_FAILED(loadingResult))
        return false;

    // Add the NavData to the Database.
    // AddToDatabaseImmediate() forces the new NavData to be added and
    // stitched immediately in the current frame. In your final game, you
    // will probably want to use AddToDatabaseAsync(), which time-slices
    // the addition of the new data over multiple frames to avoid CPU peaks.
    m_navData->Init(world->GetDatabase(0));
    m_navData->AddToDatabaseImmediate();

    ...
    return true;
}
...

void MyGameLevel::Destroy()
{
    ...
    m_navData->RemoveFromDatabaseImmediate();
    m_navData = KY_NULL;
    ...
}

class MyGameWorld
{
    ...
protected:
    ...
    MyGameLevel m_gameLevel;
    ...
};

bool MyGameWorld::Initialize()
{
    ...
    return m_gameLevel.Initialize(m_world);
}
...

void MyGameWorld::Destroy()
{
    m_gameLevel.Destroy();
    ...
}

测试

将 Navigation Lab 连接到您的游戏。

您不会立即在 Navigation Lab 的 3D 视图中看到 NavMesh。这很正常;为了避免在网络中发送数量可能很大的数据,不会将 NavData 从游戏发送到可视调试器。但是,这可能对在调试时加载 NavData 和几何体很有帮助,方便在上下文中查看从游戏中发送的调试数据。

因此,Navigation Lab 会提示您提供包含加载到游戏中的 NavData 文件的路径:

若要验证 NavData 是否已正确加载到游戏中,请打开 Profiling 面板。在 Summary 组中,NavData count 值必须大于 0。如果是使用 DefaultFileLoader 将 NavData 加载到内存中的(如以上代码示例中所示),Memory Footprint 值也将包含您数据的大小。

或者,可以渲染游戏或编辑器中的 NavData 来测试 NavData 是否正确加载。请参见渲染 NavData