本文档描述的是3.6及以后版本,对于3.5及以前的老版本请参考分类“3.5”。

有的时候,由于自身项目的需要,例如对行为树文件进行加密、打包等处理,behaviac组件默认提供的文件加载机制不再满足需要,因此程序端需要定制自己的读取方式来加载行为树文件。

C++版

1. 需要从behaviac::CFileManager派生出自己的子类,并根据需要重载相关的方法,如下代码所示:

#include "behaviac/common/file/filemanager.h"

class BEHAVIAC_API MyFileManager : public behaviac::CFileManager
{
public:
    BEHAVIAC_DECLARE_MEMORY_OPERATORS(MyFileManager);

    MyFileManager();
    virtual ~MyFileManager();

    virtual behaviac::IFile* FileOpen(const char* fileName, behaviac::CFileSystem::EOpenMode iOpenAccess = behaviac::CFileSystem::EOpenMode_Read);

    virtual void FileClose(behaviac::IFile* file);
    virtual bool FileExists(const char* fileName);
    virtual bool FileExists(const behaviac::string& filePath, const behaviac::string& ext);

    virtual uint64_t FileGetSize(const char* fileName);
    virtual behaviac::wstring GetCurrentWorkingDirectory();
};

2. 根据自己的开发平台需要,实现相应的方法,这里只是简单的调用了基类的同名方法,仅用于演示流程,如下代码所示:

#include "myfilemanager.h"

MyFileManager::MyFileManager()
{
}

MyFileManager::~MyFileManager()
{
}

behaviac::IFile* MyFileManager::FileOpen(const char* fileName, behaviac::CFileSystem::EOpenMode iOpenAccess)
{
    // 需要实现自己的代码,这里直接调用基类的方法仅供演示
    return CFileManager::FileOpen(fileName, iOpenAccess);
}

void MyFileManager::FileClose(behaviac::IFile* file)
{
    CFileManager::FileClose(file);
}

bool MyFileManager::FileExists(const behaviac::string& filePath, const behaviac::string& ext)
{
    return CFileManager::FileExists(filePath, ext);
}

bool MyFileManager::FileExists(const char* fileName)
{
    return CFileManager::FileExists(fileName);
}

uint64_t MyFileManager::FileGetSize(const char* fileName)
{
    return CFileManager::FileGetSize(fileName);
}

behaviac::wstring MyFileManager::GetCurrentWorkingDirectory()
{
    return CFileManager::GetCurrentWorkingDirectory();
}

3. 在程序端初始化的地方,创建MyFileManager实例,如下代码所示:

bool InitBehavic()
{
    LOGI("InitBehavic\n");

    g_MyFileManager = BEHAVIAC_NEW MyFileManager();

    behaviac::Workspace::GetInstance()->SetFilePath("../tutorials/tutorial_10/cpp/exported");

    behaviac::Workspace::GetInstance()->SetFileFormat(behaviac::Workspace::EFF_xml);

    return true;
}

4. 调用Agent::btload()方法,就可以通过上面实现的MyFileManager来加载行为树文件了(Agent::btload()方法内部会执行到MyFileManager::FileOpen()方法),如下代码所示:

bool InitPlayer()
{
    LOGI("InitPlayer\n");

    g_FirstAgent = behaviac::Agent::Create<FirstAgent>();

    bool bRet = g_FirstAgent->btload("FirstBT");

    g_FirstAgent->btsetcurrent("FirstBT");

    return bRet;
}

5. 在程序端结束清理的地方,销毁上面创建的MyFileManager实例,如下代码所示:

void CleanupBehaviac()
{
    LOGI("CleanupBehaviac\n");

    behaviac::Workspace::GetInstance()->Cleanup();

    if (g_MyFileManager)
    {
        BEHAVIAC_DELETE(g_MyFileManager);
        g_MyFileManager = NULL;
    }
}

C#版

1. 需要从behaviac.FileManager派生出自己的子类,并根据需要重载相关的方法,这里只是简单的调用了基类的同名方法,仅用于演示流程,如下代码所示:

public class MyFileManager : behaviac.FileManager
{
    public MyFileManager()
    {
    }

    public override byte[] FileOpen(string filePath, string ext)
    {
        // 需要实现自己的代码,这里直接调用基类的方法仅供演示
        return base.FileOpen(filePath, ext);
    }

    public override void FileClose(string filePath, string ext, byte[] fileHandle)
    {
        base.FileClose(filePath, ext, fileHandle);
    }
}

2. 在程序端初始化的地方,创建MyFileManager实例,如下代码所示:

static bool InitBehavic()
{
    Console.WriteLine("InitBehavic");

    g_MyFileManager = new MyFileManager();

    behaviac.Workspace.Instance.FilePath = "../../exported";
    behaviac.Workspace.Instance.FileFormat = behaviac.Workspace.EFileFormat.EFF_xml;

    return true;
}

3. 调用Agent.btload()方法,就可以通过上面实现的MyFileManager来加载行为树文件了(Agent.btload()方法内部会执行到MyFileManager.FileOpen()方法),如下代码所示:

static bool InitPlayer()
{
    Console.WriteLine("InitPlayer");

    g_FirstAgent = new FirstAgent();

    bool bRet = g_FirstAgent.btload("FirstBT");
    Debug.Assert(bRet);

    g_FirstAgent.btsetcurrent("FirstBT");

    return bRet;
}

4. 在程序端结束清理的地方,释放上面创建的MyFileManager实例引用,如下代码所示:

static void CleanupBehaviac()
{
    Console.WriteLine("CleanupBehaviac");

    behaviac.Workspace.Instance.Cleanup();

    g_MyFileManager = null;
}

本教程相关的工作区和代码工程详见源码包的目录tutorials/tutorial_10

发表评论

电子邮件地址不会被公开。 必填项已用*标注