本文档描述的是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。