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