<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>上手 &#8211; behaviac</title>
	<atom:link href="/language/zh/tag/%E4%B8%8A%E6%89%8B/feed/" rel="self" type="application/rss+xml" />
	<link>/</link>
	<description>Tencent behaviac, Game AI, Behavior Tree, Finite State Machine, Hierarchical Task Network, BT FSM HTN, 腾讯开源, 游戏AI, 行为树,有限状态机,分层任务网络</description>
	<lastBuildDate>Tue, 25 Jul 2017 03:06:50 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.4.1</generator>
	<item>
		<title>目录结构</title>
		<link>/directory/</link>
					<comments>/directory/#respond</comments>
		
		<dc:creator><![CDATA[jonygli]]></dc:creator>
		<pubDate>Mon, 11 Apr 2016 09:58:37 +0000</pubDate>
				<category><![CDATA[文章]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[概述]]></category>
		<guid isPermaLink="false">/?p=162</guid>

					<description><![CDATA[首先说明的是从下载链接获取的BehaviacSetup*.exe是安装包，内含可执行的编辑器及示例。 如果编辑器不能正常启动，需要下载安装Microsoft V<a class="moretag" href="/directory/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<p>首先说明的是从<a href="/language/zh/downloads/">下载链接</a>获取的BehaviacSetup*.exe是安装包，内含可执行的编辑器及示例。</p>
<p>如果编辑器不能正常启动，需要下载安装<a href="https://support.microsoft.com/en-us/kb/2977003">Microsoft Visual C++ 运行库</a>及<a href="https://www.microsoft.com/en-US/download/details.aspx?id=21">.net框架</a>。</p>
<p>可以从<a href="/language/zh/downloads/">下载链接</a>下载或从<a href="https://github.com/Tencent/behaviac">github</a>克隆源码，这里介绍的是源码的目录结构。</p>
<h3 id="section">目录结构图示</h3>
<p><img class="aligncenter size-full wp-image-1411" src="/wp-content/uploads/2016/04/directory.png" alt="directory" width="177" height="346" srcset="/wp-content/uploads/2016/04/directory.png 177w, /wp-content/uploads/2016/04/directory-153x300.png 153w" sizes="(max-width: 177px) 100vw, 177px" /></p>
<h3 id="section-1">目录结构说明</h3>
<ul>
<li>build：构建脚本，使用CMake构建。可以参考文档<a href="/language/zh/how_to_build/">《如何编译构建》</a>。</li>
<li>docs：文档，目前只有behaviac.chm，以后访问文档需要访问<a href="/">API</a></li>
<li>inc：运行时库的C++头文件</li>
<li>integration：Unity平台的实现及示例
<ul>
<li>demo_running：一个简单demo</li>
<li>unity：unity的实现及unittest</li>
</ul>
</li>
<li>projects：C++项目文件，用于打开unit test和tutorials等项目。这里的项目文件是预提供的，仅支持vs及make。如果需要其他平台，可以参考build目录下的构建脚本。</li>
<li>src：运行时库的C++源码</li>
<li>test：测试，C++
<ul>
<li>btperformance：简单的性能测试</li>
<li>btremotetest,：简单的连调测试</li>
<li>btunittest：C++ unit test</li>
<li>demo_running：简单的测试，适合少量修改，体会<a href="/docs/zh/articles/concepts/">行为树的概念</a></li>
<li>usertest：简单的测试，适合少量修改，做出自己的测试</li>
</ul>
</li>
<li>tools：编辑器的C#源码
<ul>
<li>designer</li>
</ul>
</li>
<li>tutorials：教程相关的源码，配合<a href="/language/zh/category/docs/tutorial/">教程相关文档</a>使用，方便上手</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>/directory/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>编辑器的安装</title>
		<link>/tutorial1_install/</link>
					<comments>/tutorial1_install/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:17:21 +0000</pubDate>
				<category><![CDATA[3.5]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[安装]]></category>
		<category><![CDATA[编辑器]]></category>
		<guid isPermaLink="false">/?p=267</guid>

					<description><![CDATA[首先从下载页面下载编辑器 可以查看目录结构 安装 安装behaviac套件的系统配置需求如下所示： 最低配置： 硬件环境： CPU：Intel core2 Du<a class="moretag" href="/tutorial1_install/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<p><a href="/language/zh/behaviac%E7%89%88%E6%9C%AC%E4%B8%8B%E8%BD%BD/">首先从下载页面下载编辑器</a></p>
<p><a href="/language/zh/directory/">可以查看目录结构</a></p>
<h2 id="section">安装</h2>
<p>安装behaviac套件的系统配置需求如下所示：</p>
<h3 id="section-1">最低配置：</h3>
<p>硬件环境：</p>
<p>CPU：Intel core2 Duo 2.0G或同等配置</p>
<p>内存：2GB以上</p>
<p>显卡：nvidia 6600GT或同等配置</p>
<p>软件环境：</p>
<p>操作系统：Windows XP/Vista/7/8</p>
<p>屏幕分辨率：1024*768</p>
<h3 id="section-2">推荐配置：</h3>
<p>硬件环境：</p>
<p>CPU：Intel I5 2.93G或更高配置</p>
<p>内存：4GB以上</p>
<p>显卡：nvidia GTS450或更高配置</p>
<p>软件环境：</p>
<p>操作系统：Windows 7/8</p>
<p>屏幕分辨率：1680*1050</p>
<p>运行BehaviacSetup_***.exe安装包文件，选择安装路径（推荐直接使用默认路径），安装behaviac相关套件。</p>
<p>可能需要下载安装<a href="https://support.microsoft.com/en-us/kb/2977003">Microsoft Visual C++ 运行库</a>。<br />
及<a href="https://www.microsoft.com/en-US/download/details.aspx?id=21">.net</a>。</p>
<p>安装完成后，会在桌面生成编辑器的快捷方式，如下图所示：</p>
<p><img src="/img/tutorials/tutorial1/designerIcon.png" alt="" /></p>
<p>图1 安装后桌面的编辑器图标</p>
<p>另外，在系统的“开始”菜单中生成了一些游戏demo和文档的菜单项。其中，BattleCityDemo是采用Unity引擎实现的小游戏（C#版），LaunchCocosGame是采用Cocos引擎实现的小游戏（C++版），LaunchSDLDemo是采用SDL库实现的小游戏（C++版），如下图所示：</p>
<p><img src="/img/tutorials/tutorial1/startmenu.png" alt="" /></p>
<p>图2 开始菜单中demo和文档菜单项</p>
]]></content:encoded>
					
					<wfw:commentRss>/tutorial1_install/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>编辑器的使用</title>
		<link>/tutorial2_usage/</link>
					<comments>/tutorial2_usage/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:18:49 +0000</pubDate>
				<category><![CDATA[3.5]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[编辑器]]></category>
		<guid isPermaLink="false">/?p=269</guid>

					<description><![CDATA[1 概述 behaviac中间件是我们对行为树、有限状态机等AI范式的一种整合实现方案，主要包括编辑器（Designer）和运行时库（Runtime）两大部分。<a class="moretag" href="/tutorial2_usage/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<h2 id="section"><span class="ez-toc-section" id="1">1 概述</span></h2>
<p>behaviac中间件是我们对行为树、有限状态机等AI范式的一种整合实现方案，主要包括编辑器（Designer）和运行时库（Runtime）两大部分。其中，编辑器用于编辑、导出类型信息，也用于编辑、导出和调试行为树；运行时库也可导出类型信息，主要用于解释和执行编辑器导出的行为树，运行时库需要整合到自己的游戏项目中去。</p>
<p>编辑器和运行时之间通过类型信息（Meta）进行交互，注意类型信息流动的双向箭头，表示编辑器和运行时库双方都可以导出类型信息，如下图所示：</p>
<p><img src="/img/overview/meta.png" alt="" /></p>
<p>图1 基于类型信息的编辑器和运行时端的交互</p>
<p>编辑器只能运行在Windows平台上，运行时库支持C++和C#语言两个版本，对Unity引擎原生支持C#，运行时库目前支持所有主流平台，包括Windows/Linux/Android/iOS等。</p>
<p>该组件的使用场景，支持但不限于游戏中的逻辑、角色的人工智能、动画的控制等方面。</p>
<h2 id="section-1"><span class="ez-toc-section" id="2">2 编辑器的使用</span></h2>
<h3 id="section-2"><span class="ez-toc-section" id="21">2.1 基本介绍</span></h3>
<p>编辑器首次打开后为会根据操作系统的语言环境配置自动设置为中文版或英文版的界面，若需更改语言显示，可以依次选择菜单项“文件（File）”-&gt;“设置（Settings）”，在弹出的设置对话框中，选择需要的“语言（Language）”并点击“确认（OK）”后，退出并重新打开编辑器，则转为需要语言的界面。<br />
编辑器主要分为几个部分：菜单和工具栏、行为树文件区、节点区、主视口和属性表等，如下图所示：</p>
<p><img src="/img/tutorials/tutorial2/designerMainWindow.png" alt="" /></p>
<p>图2.1 编辑器主界面</p>
<ul>
<li>菜单和工具栏：主要有新建/打开工作区、新建/保存/导出/关闭行为树文件、设置、退出、帮助等菜单项或按键。</li>
<li>行为树文件区：列出了当前打开的工作区里面的所有行为树文件，双击某个行为树文件节点可以打开该文件。</li>
<li>节点区：给出了behaviac组件支持的所有行为树节点类型，在编辑行为树的时候，可以通过鼠标拖拽添加到主视口的行为树上去。</li>
<li>主视口：显示了当前打开的行为树图形，可以打开多个行为树，分页显示。</li>
<li>属性表：在主视口中点击选择某个节点后，属性表会更新显示当前选中节点的所有属性，可以编辑各个属性。</li>
</ul>
<p>所有窗口的停靠位置均可根据个人喜好，通过鼠标在窗口边框的拖拽重新布局。编辑器中所有的按钮均可将鼠标停在上面查看其tips，以便查知其功能。编辑器中鼠标、键盘的按键用法介绍，请查看菜单中的“帮助（Help）”-&gt;“起始页（StartPage）”。</p>
<p>编辑器分为三种操作模式：<br />
&#8211; 编辑模式：这是常规模式，编辑器启动后默认进入该模式，主要用于为游戏项目编辑所需的类型信息和行为树。<br />
&#8211; 连接模式：这是编辑器连接上游戏之后进入的模式，此时不能编辑行为树本身，只能用于观察行为树的高亮执行路径、设置断点等调试相关的操作。<br />
&#8211; 分析模式：这是离线模式，在断开游戏时保存了连接过程中的所有消息，在该模式可以模拟连接模式游戏端发送过来的消息，进行离线分析行为树的执行情况。</p>
<h3 id="section-3"><span class="ez-toc-section" id="22">2.2 操作说明</span></h3>
<h4 id="section-4"><span class="ez-toc-section" id="221">2.2.1 新建工作区</span></h4>
<p>首次使用编辑器，需要为自己的项目创建一个工作区：</p>
<ul>
<li>点击菜单“文件”-&gt;“新建工作区”，弹出新建工作区对话框，如下图所示。</li>
</ul>
<p><img src="/img/tutorials/tutorial2/newWorkspace.png" alt="" /></p>
<p>图2.2.1 新建工作区</p>
<ul>
<li>依次设置工作区的名字、位置（即工作区的保存路径）、源位置（即原始行为树的保存路径）、导出位置（即运行时库所需行为树的导出路径）和元数据位置（即运行时库导出的类型信息文件路径）。</li>
<li>源位置是存放编辑器创建的行为树的位置。导出位置是存放导出的行为树的位置。源位置和导出位置缺省情况下位于工作区所在的目录内：behaviors和exported。</li>
<li>元数据位置、源位置和导出位置需要和工作区文件必须位于同一个盘符下（如果位于不同的盘符下，调试的时候会有问题）。缺省情况下，它们位于同一个顶级目录下。</li>
</ul>
<h4 id="section-5"><span class="ez-toc-section" id="222">2.2.2 打开工作区</span></h4>
<p>点击菜单“文件”-&gt;“打开工作区”，选择保存在磁盘上的*.workspace.xml文件。<br />
在安装路径下有提供的例子供参考，例如默认安装路径下的“C:\Program Files (x86)\behaviac\integration\BattleCityDemo\Assets\BTWorkspace\BattleCity.workspace.xml”，或者从菜单中的“文件”-&gt;“最近打开的工作区”列表中选择最近打开过的工作区。<br />
behaviac组件提供了C++和C#两种编程语言的单元测试以及游戏Demo，可以通过编辑器中的菜单项“帮助”-&gt;“控制说明” 进入，然后点击快速打开所需的单元测试或游戏Demo所用到的工作区，如下图所示：</p>
<p><img src="/img/tutorials/tutorial2/demoUnittest.png" alt="" /></p>
<p>图2.2.2 快速打开单元测试和游戏Demo的工作区</p>
<h4 id="section-6"><span class="ez-toc-section" id="223">2.2.3 编辑工作区</span></h4>
<p>点击菜单“文件”-&gt;“编辑工作区”，可以修改该工作区的设置（名字、元数据位置、源位置、导出位置等），如下图所示：</p>
<p><img src="/img/tutorials/tutorial2/editWorkspace.png" alt="" /></p>
<p>图2.2.3 编辑工作区</p>
<h4 id="section-7"><span class="ez-toc-section" id="224">2.2.4 新建并编辑行为树文件</span></h4>
<ul>
<li>在打开的工作区中，从工具栏里面点击“新建行为树”按钮或者通过菜单中“文件”-&gt;“新建行为树”项，创建一个行为树文件。</li>
<li>在主视口中，为新建的行为树根节点选择设置其“Agent类型”。</li>
<li>在“节点区”中用鼠标左键选择并拖拽一些节点到主视口中来构建需要的行为树，并设置每个节点的属性。每种节点的具体用法请参考菜单项“帮助”-&gt;“节点介绍”。</li>
<li>编辑过程中，支持Undo/Redo、保存等文件操作，鼠标、键盘的按键用法请对照菜单项“帮助”-&gt;“控制说明”。</li>
</ul>
<h4 id="section-8"><span class="ez-toc-section" id="225">2.2.5 打开行为树文件</span></h4>
<p>如图2.1所示，在“行为树文件区”中，双击某个行为树文件节点就可以在主视口中打开该文件。</p>
<h4 id="section-9"><span class="ez-toc-section" id="226">2.2.6 导出行为树文件</span></h4>
<ul>
<li>编辑完行为树之后，可以通过菜单项“文件”-&gt;“导出行为树”（或者快捷键Ctrl+T）导出当前打开的行为树文件。</li>
<li>通过菜单项“文件”-&gt;“导出全部”项（或者快捷键Ctrl+Shift+T）导出工作区中的所有行为树文件。</li>
<li>目前支持4种文件格式的导出，即XML、BSON、C++和C#，如下图所示：</li>
</ul>
<p><img src="/img/tutorials/tutorial2/exportBehaviors.png" alt="" /></p>
<p>图2.2.6.1 导出行为树</p>
<ul>
<li>对于C++/C#格式的导出，还可以设置导出的文件名和位置。点击图2.2.6.1中“导出设置”-&gt;“设置”列的“…”按钮，可以弹出“C++/C#导出设置”对话框。对于C++文件，还需添加游戏项目中Agent子类的.h头文件，如图2.2.6.2所示。<br />
导出后，将在指定的导出路径下生成behaviac_generated目录，里面又包含了behaviors和types两个子目录，需要将这两个子目录里面的所有文件全部包含到自己的项目中去。<br />
注意：对于导出C++文件，如果不添加Agent子类的.h头文件，那么需要注意将behaviors和types两个子目录中生成的头文件放在项目代码include “yourAgent.h”之后，以确保Agent子类先被包含进来，否则会有编译错误。</li>
</ul>
<p><img src="/img/tutorials/tutorial2/exportSettings.png" alt="" /></p>
<p>图2.2.6.2 C++/C#的导出设置</p>
<ul>
<li>图2.2.6.2中的选项“是否导出统一文件”用来表示导出的C++或者C#文件是否为一个统一的大文件还是若干个小文件，其中每个小文件对应一个行为树。</li>
<li>运行时库支持行为树导出文件的热加载，如果在编辑器修改完行为树之后，重新导出，游戏端会自动重新加载所用到的行为树，无需重启游戏。</li>
</ul>
<h4 id="section-10"><span class="ez-toc-section" id="227_Permalink">2.2.7 连接游戏<a class="header-link" title="Permalink" href="/docs/zh/tutorials/tutorial2_usage/#section-10"><span class="sr-only">Permalink</span><i class="fa fa-link"></i></a></span></h4>
<ul>
<li>从开始菜单中，启动小游戏BattleCityDemo，如下图所示：</li>
</ul>
<p><img src="/img/tutorials/tutorial2/battleCityDemo.png" alt="" /></p>
<p>图2.2.7.1 Battle City Demo</p>
<ul>
<li>点击游戏主界面右上角的“Show Levels”按钮，可以切换不同的关卡，如下图所示：</li>
</ul>
<p><img src="/img/tutorials/tutorial2/selectGameLevel.png" alt="" /></p>
<p>图2.2.7.2 选择关卡</p>
<ul>
<li>点击游戏主界面左下角的“Launch Designer”按钮，启动编辑器，编辑器会自动打开BattleCityDemo的工作区，并打开游戏当前关卡所用到的行为树（如果没有切换其他关卡，默认打开的是Tank_Fire_Random行为树文件）。</li>
<li>点击编辑器工具栏中的“连接游戏”按钮或通过菜单项“文件”-&gt;“连接游戏”（或通过快捷键Ctrl+L），开始连接游戏。默认的，一般无需更改服务器IP和端口号，如图2.2.7.3所示。<br />
注意：有时候可能会发现连不上游戏，很可能是原来的端口号已被占用，可以尝试在运行时端的端口号60636改为其他值，然后相应的修改图2.2.7.3中的端口号，尝试重新连接游戏。</li>
</ul>
<p><img src="/img/tutorials/tutorial2/connectGame.png" alt="" /></p>
<p>图2.2.7.3 连接游戏</p>
<ul>
<li>连接成功后，编辑器从编辑模式切换到连接模式，如下图所示：</li>
</ul>
<p><img src="/img/tutorials/tutorial2/connectMode.png" alt="" /></p>
<p>图2.2.7.4 连接模式</p>
<ul>
<li>时间轴（Timeline）：默认位于编辑器最上方，用于表示当前帧相关的信息。</li>
<li>实例列表：列出了游戏中所有的对象实例，双击实例节点后可以开始跟踪调试选中的实例，右键单击实例节点弹出如下菜单，如图2.2.7.5所示。其中“调试”跟双击节点的作用一致，开始跟踪选中的实例，主视口会高亮显示行为树的执行路径；“查看属性”用于跟踪当前选中实例的所有属性的变化，编辑器会弹出实例的属性列表。</li>
</ul>
<p><img src="/img/tutorials/tutorial2/debugInstance.png" alt="" /></p>
<p>图2.2.7.5 实例右键菜单</p>
<ul>
<li>主视口：高亮的节点边框和连接线段，表示程序当前执行的路径情况。双击树中节点的左右两侧，可以设置节点的断点（左侧表示进入断点，右侧表示退出断点），用于游戏执行时在断点位置停下来，游戏断下来后按F5键后继续运行。</li>
<li>输出窗口：列出了收到的全部消息，用于调试时查看记录。</li>
<li>Agent的属性：可以显示当前Agent属性的变化。</li>
<li>断点：通过菜单项“视图”-&gt;“断点”打开断点窗口后，可以查看、管理当前工作区中的所有断点。</li>
</ul>
<h4 id="section-11"><span class="ez-toc-section" id="228">2.2.8 分析导出数据</span></h4>
<ul>
<li>点击菜单或工具栏中的“断开游戏”按键，断开与游戏端的连接，回到编辑模式。</li>
<li>默认弹出如下对话框，保存之前连接模式下调试的相关数据。</li>
</ul>
<p><img src="/img/tutorials/tutorial2/saveDump.png" alt="" /></p>
<p>图2.2.8.1 保存dump数据</p>
<ul>
<li>点击菜单或工具栏中的“分析导出文件”按键，选择打开上一步导出的数据文件，编辑器进入到分析模式。</li>
<li>分析模式的界面布局跟连接模式类似，但是可以通过时间轴里面的播放按钮开始重现连接过程中的情况，如下图所示：</li>
</ul>
<p><img src="/img/tutorials/tutorial2/analyzeDump.png" alt="" /></p>
<p>图2.2.8.2 分析dump数据</p>
<ul>
<li>要退出分析模式，可以点击菜单或工具栏中的“终止分析”按键，回到编辑模式。</li>
</ul>
<p>需要指出的是，分析模式下还可以直接下载_behaviac_$_.log文件进行离线分析。_behaviac_$_.log文件一般生成在exe所在的目录。对于unity，_behaviac_$_.log文件生成在Assets所在的目录中。</p>
<h4 id="section-12"><span class="ez-toc-section" id="229">2.2.9 其他</span></h4>
<p>除了BattleCityDemo小游戏（基于Unity引擎实现，运行时库为C#版）之外，还有LaunchCocosGame（基于Cocos引擎实现，运行时库为C++版）和LaunchSDLDemo小游戏（基于SDL库实现，运行时库为C++版）。<br />
如图2.2所示，从操作系统的开始菜单中启动LaunchCocosGame或LaunchSDLDemo小游戏后，游戏跟编辑器的连接需要单独启动编辑器，然后再点击编辑器工具栏中的“连接游戏”按钮或通过菜单项“文件”-&gt;“连接游戏”（快捷键Ctrl+L），开始连接游戏。连接后，执行情况跟BattleCityDemo小游戏类似。</p>
<div class="section-nav"></div>
]]></content:encoded>
					
					<wfw:commentRss>/tutorial2_usage/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>如何编译构建</title>
		<link>/how_to_build/</link>
					<comments>/how_to_build/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:43:18 +0000</pubDate>
				<category><![CDATA[文章]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[编译构建]]></category>
		<guid isPermaLink="false">/?p=308</guid>

					<description><![CDATA[如何编译构建 请首先到/language/zh/downloads/下载或克隆源码。 C++运行时库的构建 请参考<a class="moretag" href="/how_to_build/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<h2><span class="ez-toc-section" id="i">如何编译构建</span></h2>
<p id="section">请首先到<a href="/language/zh/downloads/#https://github.com/Tencent/behaviac">/language/zh/downloads/</a>下载或克隆源码。</p>
<h3 id="c"><span class="ez-toc-section" id="C">C++运行时库的构建</span></h3>
<p>请参考文档《<a href="/docs/zh/articles/build/">使用cmake构建C++版运行时库</a>》。</p>
<h4><span class="ez-toc-section" id="i-2">项目文件</span></h4>
<p>从3.6.33版本，我们提供了预先生成的项目文件，如下图：</p>
<p id="NgRlqmF"><img class="alignnone size-full wp-image-2062 " src="/wp-content/uploads/2017/07/img_5976b5154fe90.png" alt="" srcset="/wp-content/uploads/2017/07/img_5976b5154fe90.png 558w, /wp-content/uploads/2017/07/img_5976b5154fe90-300x110.png 300w" sizes="(max-width: 558px) 100vw, 558px" /></p>
<h3><span class="ez-toc-section" id="CUnity">C#和Unity运行时库的构建</span></h3>
<p>安装目录中的/integration/unity是基于Unity C#的单元测试项目。</p>
<p>自己的C#项目需要将目录/integration/unity/Assets/Scripts/behaviac/runtime下的所有源码直接复制过去，如下图所示：</p>
<p><img class="aligncenter size-full wp-image-1365" src="/wp-content/uploads/2016/05/unity_runtime.png" alt="unity_runtime" width="453" height="579" srcset="/wp-content/uploads/2016/05/unity_runtime.png 453w, /wp-content/uploads/2016/05/unity_runtime-235x300.png 235w" sizes="(max-width: 453px) 100vw, 453px" /></p>
<p>如果是Unity平台下的C#开发，还可以在Unity编辑器中导入/integration/behaviac.unitypackage包（安装完发布的BehaviacSetup_***.exe后，会在安装目录中的/integration文件夹中找到该behaviac.unitypackage包）。</p>
<h3><span class="ez-toc-section" id="i-3">编辑器的构建</span></h3>
<p>编辑器的源码目录结构，如下图所示：<br />
<img src="/img/faq/source_designer_path.png" alt="source_designer_path.png" /></p>
<p>请使用vs2010或以上打开并构建<code class="highlighter-rouge">tools/designer/BehaviacDesigner.sln</code>。</p>
]]></content:encoded>
					
					<wfw:commentRss>/how_to_build/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>VS项目中使用behaviac组件</title>
		<link>/cpp_include/</link>
					<comments>/cpp_include/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:44:04 +0000</pubDate>
				<category><![CDATA[文章]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[编译构建]]></category>
		<category><![CDATA[运行时]]></category>
		<guid isPermaLink="false">/?p=311</guid>

					<description><![CDATA[下载完behaviac组件的全部源码后，整个组件的目录结构，如下图所示： 将behaviac组件整合到自己的项目中时，可以通过两种方式使用behaviac组件：<a class="moretag" href="/cpp_include/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<p id="cbehaviac">下载完behaviac组件的全部源码后，整个组件的目录结构，如下图所示：</p>
<p><img src="/img/tutorials/tutorial16/sourceFolder.png" alt="" /></p>
<p>将behaviac组件整合到自己的项目中时，可以通过两种方式使用behaviac组件：</p>
<ul>
<li>将全部源码（包括behaviac组件的所有<a href="https://github.com/Tencent/behaviac/blob/master/inc/behaviac">.h</a>和<a href="https://github.com/Tencent/behaviac/blob/master/src">.cpp</a>文件）全部复制到自己的游戏项目中。</li>
<li>单独编译behaviac组件库，生成lib文件，然后自己的项目包含.h文件和生成的.lib文件。</li>
</ul>
<p>对于上面的第二种用法，请先参考<a href="/docs/zh/tutorials/how_to_build/">如何编译构建</a>文档来编译构建behavaic组件。</p>
<p>在Windows平台，如果是使用VS来管理项目的，需要在VS的项目“Property Pages”-&gt;“Configuration Properties”-&gt;“C/C++”-&gt;“General”中的“Additional Include Directories”项中添加behaviac组件头文件（即图1中的inc文件夹）所在的路径，如下图所示：</p>
<p><img src="/img/tutorials/tutorial16/includeHeaderSettings.png" alt="" /></p>
<p>再在VS的项目“Property Pages”-&gt;“Configuration Properties”-&gt;“Linker”-&gt;“General”中的“Additional Library Directories”项中添加自己编译出的behaviac lib文件（即图1中的lib文件夹）所在的路径，如下图所示：</p>
<p><img src="/img/tutorials/tutorial16/includeLibSettings.png" alt="" /></p>
<p>最后在VS的项目“Property Pages”-&gt;“Configuration Properties”-&gt;“Linker”-&gt;“Input”中的“Additional Dependencies”项中添加自己编译出的behaviac lib文件，如下图所示：</p>
<p><img src="/img/tutorials/tutorial16/addLibSettings.png" alt="" /></p>
<p>注意：上图中的behaviac_debugdll_win32_vs2010.lib文件是用VS2010编译出来的，说明游戏项目也需要用VS2010来编译。如果你的游戏项目使用其他版本的VS，则编译behaviac组件也需要用相应版本的VS来编译。</p>
]]></content:encoded>
					
					<wfw:commentRss>/cpp_include/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>C++运行时端的使用上手</title>
		<link>/tutorial14_cpp_workflow/</link>
					<comments>/tutorial14_cpp_workflow/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:21:24 +0000</pubDate>
				<category><![CDATA[3.5]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[运行时]]></category>
		<guid isPermaLink="false">/?p=273</guid>

					<description><![CDATA[运行时（游戏）端使用行为树之前，需要确保行为树文件已经成功导出。 如何注册和导出类型信息请参考C++类型信息的注册和导出，如何导出行为树请参考导出和使用XML/<a class="moretag" href="/tutorial14_cpp_workflow/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<p id="c">运行时（游戏）端使用行为树之前，需要确保行为树文件已经成功导出。</p>
<p>如何注册和导出类型信息请参考<a href="/docs/zh/tutorials/tutorial3_1_meta_cpp_register/">C++类型信息的注册和导出</a>，如何导出行为树请参考<a href="/docs/zh/tutorials/tutorial4_1_export_xml_bson/">导出和使用XML/BSON行为树</a>。</p>
<p>通过编辑器导出行为树文件后，运行时端的执行主要分为三个部分：</p>
<ul>
<li>初始化</li>
<li>循环更新</li>
<li>清理</li>
</ul>
<h3 id="section"><span class="ez-toc-section" id="1">1 初始化</span></h3>
<p>在游戏的初始化函数中，添加初始化behaviac组件所需的功能，例如注册Agent子类信息、设置行为树文件的加载路径和文件格式、创建Agent子类的实例、加载行为树并设置当前所需执行的行为树等。</p>
<p>如下代码所示：</p>
<div class="highlighter-rouge">
<pre class="highlight"><code><span class="n">bool</span> <span class="nf">InitBehavic</span><span class="p">(</span><span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">EFileFormat</span> <span class="n">ff</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Config</span><span class="o">::</span><span class="n">SetSocketBlocking</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Config</span><span class="o">::</span><span class="n">SetSocketPort</span><span class="p">(</span><span class="mi">8081</span><span class="p">);</span>

    <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">Register</span><span class="o">&lt;</span><span class="n">CBTPlayer</span><span class="o">&gt;</span><span class="p">();</span>

    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">SetFilePath</span><span class="p">(</span><span class="s">"../test/demo_running/behaviac/exported"</span><span class="p">);</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">SetFileFormat</span><span class="p">(</span><span class="n">ff</span><span class="p">);</span>

    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">ExportMetas</span><span class="p">(</span><span class="s">"../test/demo_running/behaviac/demo_running.xml"</span><span class="p">);</span>

    <span class="c1">//behaviac::Agent::SetIdMask(kIdMask_Wolrd | kIdMask_Opponent);
</span>    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">SetDeltaFrames</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>

    <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">bool</span> <span class="nf">InitPlayer</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">pszTreeName</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">g_player</span> <span class="o">=</span> <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">Create</span><span class="o">&lt;</span><span class="n">CBTPlayer</span><span class="o">&gt;</span><span class="p">();</span>

    <span class="n">bool</span> <span class="n">bRet</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
    <span class="n">bRet</span> <span class="o">=</span> <span class="n">g_player</span><span class="o">-&gt;</span><span class="n">btload</span><span class="p">(</span><span class="n">pszTreeName</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="n">bRet</span><span class="p">);</span>

    <span class="n">g_player</span><span class="o">-&gt;</span><span class="n">btsetcurrent</span><span class="p">(</span><span class="n">pszTreeName</span><span class="p">);</span>

    <span class="k">return</span> <span class="n">bRet</span><span class="p">;</span>
<span class="p">}</span>

</code></pre>
</div>
<div class="note info">
<h5><span class="ez-toc-section" id="i">关于文件路径的说明</span></h5>
</div>
<ul>
<li>Workspace::SetFilePath指定的是编辑器中Workspace的导出路径，可以是绝对路径。当指定的是相对路径的时候，相对的是当前<strong>工作路径</strong>（一般都是运行程序所在目录）。</li>
<li>Agent::btload使用的文件名是相对于Workspace::SetFilePath指定的路径，没有扩展名，可以有目录结构的层次化文件名，如“node_test/selector_loop_ut_7”。在编辑器中打开某个行为树后，右键文件页选取“复制文件名”获取。</li>
</ul>
<p><img src="/img/tutorials/tutorial14/copy_filepath.png" alt="copy_filepath" /></p>
<ul>
<li>例如：
<ul>
<li>如果运行程序所在目录（或者VS里指定的工作路径$(TargetDir)）是”D:\Test\bin”</li>
<li>Workspace::SetFilePath指定的相对路径是“../behaviac/workspace/exported”</li>
<li>btload指定是“node_test/selector_loop_ut_7”</li>
<li>则workspace的导出路径实际是“D:/Test/behaviac/workspace/exported”，<br />
而相应的导出行为树文件是“D:/Test/behaviac/workspace/exported/node_test/selector_loop_ut_7.xml”或<br />
“D:/Test/behaviac/workspace/exported/node_test/selector_loop_ut_7.bson.bytes”。</li>
<li>具体是xml或bson则由Workspace::SetFileFormat确定。</li>
<li>当指定格式是cpp或c#的时候，导出的行为树是cpp或c#源码，已经编译构建进可执行程序，Agent::btload指定的文件名（跟xml的用法一样，无需修改btload的参数）只是用来标识该行为树的，从而代码可以据此创建相应的行为树，不像xml或bson格式的时候需要加载数据文件。</li>
</ul>
</li>
<li>如果Agent::btload加载失败，请注意检查当前路径，Workspace::SetFilePath设定的导出路径，以及Agent::btload指定的文件标识。还可以在当前路径里检查log文件<code class="highlighter-rouge">_behaviac_$_$_.log</code></li>
</ul>
<h3 id="section-1"><span class="ez-toc-section" id="2">2 循环更新</span></h3>
<p>在游戏的主循环中，添加执行Agent实例的行为树相关代码，也即通过调用Agent类的接口btexec()或Workspace类的接口Update()来执行行为树。</p>
<p>这两种执行方式的区别，请参考<a href="/docs/zh/tutorials/tutorial13_updateloop/">更新流程</a>。</p>
<p>如下代码样例所示：</p>
<div class="highlighter-rouge">
<pre class="highlight"><code>
<span class="kt">void</span> <span class="nf">UpdateLoop</span><span class="p">()</span>
<span class="p">{</span>
	<span class="kt">int</span> <span class="n">i</span>  <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="kt">int</span> <span class="n">frames</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">behaviac</span><span class="o">::</span><span class="n">EBTStatus</span> <span class="n">status</span> <span class="o">=</span> <span class="n">behaviac</span><span class="o">::</span><span class="n">BT_RUNNING</span><span class="p">;</span>

	<span class="k">while</span> <span class="p">(</span><span class="n">status</span> <span class="o">==</span> <span class="n">behaviac</span><span class="o">::</span><span class="n">BT_RUNNING</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"frame "</span> <span class="o">&lt;&lt;</span> <span class="o">++</span><span class="n">frames</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
		<span class="n">status</span> <span class="o">=</span> <span class="n">g_player</span><span class="o">-&gt;</span><span class="n">btexec</span><span class="p">();</span>
	<span class="p">}</span>
<span class="p">}</span>

</code></pre>
</div>
<h3 id="section-2"><span class="ez-toc-section" id="3">3 清理</span></h3>
<p>最后的清理过程，包括销毁Agent子类的实例，以及反注册Agent子类信息等。</p>
<p>如下代码样例所示：</p>
<div class="highlighter-rouge">
<pre class="highlight"><code>
<span class="kt">void</span> <span class="nf">CleanupPlayer</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">Destroy</span><span class="p">(</span><span class="n">g_player</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">CleanupBehaviac</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">UnRegister</span><span class="o">&lt;</span><span class="n">CBTPlayer</span><span class="o">&gt;</span><span class="p">();</span>

	<span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">Cleanup</span><span class="p">();</span>
<span class="p">}</span>

</code></pre>
</div>
<p>以上步骤的完整代码，请参考<a href="https://github.com/Tencent/behaviac/blob/master/test/demo_running/demo_running.cpp">demo_running.cpp</a>文件。</p>
]]></content:encoded>
					
					<wfw:commentRss>/tutorial14_cpp_workflow/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>导出和使用C++行为树</title>
		<link>/tutorial4_2_export_cpp/</link>
					<comments>/tutorial4_2_export_cpp/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:29:06 +0000</pubDate>
				<category><![CDATA[3.5]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[编辑器]]></category>
		<guid isPermaLink="false">/?p=284</guid>

					<description><![CDATA[在“导出行为树”对话框中，选择“C++ Behavior Exporter”，如下图所示： 点击上图中右侧的“…”设置按钮，在弹出的“C++导出设置”对话框中设<a class="moretag" href="/tutorial4_2_export_cpp/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<ul>
<li>在“导出行为树”对话框中，选择“C++ Behavior Exporter”，如下图所示：</li>
</ul>
<p><img class="aligncenter" src="/img/tutorials/tutorial4/exportCpp.png" alt="" /></p>
<ul>
<li>点击上图中右侧的“…”设置按钮，在弹出的“C++导出设置”对话框中设置生成文件所在的位置，并可以添加项目中游戏类（从Agent类派生而来）所在的.h头文件，添加的头文件将会被包含在生成的.cpp文件中，如下图所示：</li>
</ul>
<p><img class="aligncenter" src="/img/tutorials/tutorial4/cppExportSettings.png" alt="" /></p>
<ul>
<li>回到“导出行为树”对话框，点击“导出”按钮，开始导出<code class="highlighter-rouge">C++</code>文件。在指定的导出位置（默认为当前工作区的导出路径）会自动生成一个名为<code class="highlighter-rouge">behaviac_generated</code>的文件夹，里面生成了<code class="highlighter-rouge">behaviors</code>和<code class="highlighter-rouge">types</code>两个子文件夹，如图3所示：</li>
<li><code class="highlighter-rouge">behaviors</code>文件夹中含有<code class="highlighter-rouge">generated_behaviors.h</code>及其他单个的行为树<code class="highlighter-rouge">.inl</code>文件（如果没有勾选“导出统一文件？”，则对每一棵行为树都会生成独立的<code class="highlighter-rouge">.inl</code>文件，这些.inl文件会自动include在<code class="highlighter-rouge">generated_behaviors.h</code>文件中，无需在自己的项目中再include这些<code class="highlighter-rouge">.inl</code>文件，只需要include这个<code class="highlighter-rouge">generated_behaviors.h</code>文件即可）。</li>
<li><code class="highlighter-rouge">types</code>文件夹中含有<code class="highlighter-rouge">agentproperties.h</code>（为Agent类自定义的属性和方法，会扩展在该文件中）、<code class="highlighter-rouge">customizedtypes.h/customizedtypes.cpp</code>（自定义的枚举和结构体类型，会生成在这两个文件中）以及其他自定义<code class="highlighter-rouge">Agent</code>子类的文件（这些文件是为添加的<code class="highlighter-rouge">Agent</code>子类自动生成的<code class="highlighter-rouge">.h/.cpp</code>文件，需要程序员补充代码进一步实现这些<code class="highlighter-rouge">Agent</code>子类的逻辑）。</li>
</ul>
<p><img class="aligncenter" src="/img/tutorials/tutorial4/exportedCppFiles.png" alt="" /></p>
<ul>
<li>注意：这些自动生成的文件（除了上面提及的单个的行为树<code class="highlighter-rouge">.inl</code>文件之外）都需要包含到自己的游戏项目中，一起参与整个项目代码的编译和构建。</li>
<li>在项目中包含了这些自动生成的代码文件后，就可以与前面提及的<a href="/docs/zh/tutorials/tutorial4_1_export_xml_bson/">导出和使用XML/BSON行为树</a>一样的接口和方式加载使用这些C++文件，只是需要将文件格式改为<code class="highlighter-rouge">EFF_cpp</code>：</li>
</ul>
<div class="highlighter-rouge">
<pre class="highlight"><code>
<span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">SetFileFormat</span><span class="p">(</span><span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">EFF_cpp</span><span class="p">);</span>

</code></pre>
</div>
<div class="section-nav"></div>
]]></content:encoded>
					
					<wfw:commentRss>/tutorial4_2_export_cpp/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>C++运行时端中元信息的注册和导出</title>
		<link>/tutorial3_1_meta_cpp_register/</link>
					<comments>/tutorial3_1_meta_cpp_register/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:23:51 +0000</pubDate>
				<category><![CDATA[3.5]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[运行时]]></category>
		<guid isPermaLink="false">/?p=276</guid>

					<description><![CDATA[behaviac组件的基本运作机制就是在运行时端（C++）和编辑器通过元信息进行交互，如图1所示。其中，元信息里面包含了类自身的描述、属性、方法及类的实例等。 <a class="moretag" href="/tutorial3_1_meta_cpp_register/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<p id="c">behaviac组件的基本运作机制就是在运行时端（C++）和编辑器通过元信息进行交互，如图1所示。其中，元信息里面包含了类自身的描述、属性、方法及类的实例等。</p>
<p><img class="aligncenter" src="/img/overview/meta.png" alt="" /></p>
<p style="text-align: center;">图1 基于元信息的编辑器和运行时端的交互</p>
<p>在运行时端，也即游戏代码端，通过注册（C++通过宏的方式）并导出供行为树引擎和编辑器使用的XML元信息。运行时端主要是由程序员编写Agent的子类及其属性和方法，然后调用相关接口将这些元信息导出，就可以在编辑器中对这些元信息进行使用。</p>
<p>在编辑器中也可以创建和编辑元信息。在项目开始初期，也就是程序员还没把代码写出来之前，策划就可以自己手动的创建一些Agent子类、属性和方法等元信息。这样可以加速游戏原型的创建，也就是策划不用等程序员，就可以进行游戏原型的编辑。</p>
<p>整个工作流程主要分为以下几个步骤：</p>
<h3 id="section">1 注册元信息</h3>
<ul>
<li>在.h文件中，根据项目需要按以下步骤编写自己的游戏类：
<ul>
<li>首先需要包含头文件#include “behaviac/behaviac.h”。</li>
<li>该类需要从behaviac::Agent基类继承。</li>
<li>首先用宏DECLARE_BEHAVIAC_AGENT声明该类及其父类，用于行为树引擎内部的反射系统所需的类型信息。</li>
<li>为该类添加必要的属性和方法等。</li>
</ul>
</li>
</ul>
<p>如下代码样例所示：</p>
<div class="highlighter-rouge">
<pre class="highlight"><code>
<span class="cp">#include "behaviac/behaviac.h"
</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">behaviac</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">CBTPlayer</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Agent</span>
<span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
    <span class="n">DECLARE_BEHAVIAC_AGENT</span><span class="p">(</span><span class="n">CBTPlayer</span><span class="p">,</span> <span class="n">Agent</span><span class="p">);</span>

    <span class="n">CBTPlayer</span><span class="p">();</span>
    <span class="k">virtual</span> <span class="o">~</span><span class="n">CBTPlayer</span><span class="p">();</span>

    <span class="kt">time_t</span> <span class="n">GetCurTime</span><span class="p">();</span>
    <span class="n">bool</span> <span class="n">Condition</span><span class="p">();</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">EBTStatus</span> <span class="n">Action1</span><span class="p">();</span>
    <span class="n">EBTStatus</span> <span class="n">Action3</span><span class="p">();</span>

<span class="k">private</span><span class="o">:</span>
    <span class="kt">int</span>                 <span class="n">m_iX</span><span class="p">;</span>
    <span class="kt">int</span>                 <span class="n">m_iY</span><span class="p">;</span>
    <span class="kt">unsigned</span> <span class="kt">int</span>        <span class="n">m_iBaseSpeed</span><span class="p">;</span>
    <span class="kt">int</span>					<span class="n">m_Frames</span><span class="p">;</span>
<span class="p">};</span>

</code></pre>
</div>
<ul>
<li>在.cpp文件中，通过一系列宏来注册该类自身的描述及其属性与方法：
<ul>
<li>宏BEGIN_PROPERTIES_DESCRIPTION和END_PROPERTIES_DESCRIPTION表示类型信息注册的开始和结束。</li>
<li>宏CLASS_DISPLAYNAME和CLASS_DESC用于注册类自身的显示名和描述。</li>
<li>宏REGISTER_PROPERTY用于注册类的属性，可以通过.DISPLAYNAME的追加方式为属性添加显示名，通过.DESC的追加方式为属性添加描述。</li>
<li>宏REGISTER_METHOD用于注册类的方法，可以通过.DISPLAYNAME的追加方式为方法添加显示名，通过.DESC的追加方式为方法添加描述，通过.PARAM_DISPLAY_INFO的追加方式为参数添加显示名和描述等。如果参数类型是数值类型（例如int、unsigned int、float等），.PARAM_DISPLAY _INFO还可以用来指定参数的有效范围。</li>
</ul>
</li>
</ul>
<p>如下代码样例所示：</p>
<div class="highlighter-rouge">
<pre class="highlight"><code>
<span class="n">BEGIN_PROPERTIES_DESCRIPTION</span><span class="p">(</span><span class="n">CBTPlayer</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">REGISTER_PROPERTY</span><span class="p">(</span><span class="n">m_iBaseSpeed</span><span class="p">);</span>

	<span class="n">REGISTER_METHOD</span><span class="p">(</span><span class="n">Condition</span><span class="p">);</span>
	<span class="n">REGISTER_METHOD</span><span class="p">(</span><span class="n">Action1</span><span class="p">);</span>
	<span class="n">REGISTER_METHOD</span><span class="p">(</span><span class="n">Action3</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">END_PROPERTIES_DESCRIPTION</span><span class="p">()</span>

</code></pre>
</div>
<h3 id="section-1">2 导出元信息</h3>
<p>注册完类信息之后，按以下步骤导出元数据文件：</p>
<ul>
<li>在初始化函数里，添加Agent::Register&lt;***&gt;()用于注册类信息到引擎库中。</li>
<li>通过Agent::RegisterInstanceName&lt;***&gt;(…)来注册类的实例名。</li>
<li>调用Workspace::GetInstance()-&gt;SetFilePath(…)设置元信息文件导出的位置。</li>
<li>调用Workspace::GetInstance()-&gt;ExportMetas(…)导出元信息文件。</li>
<li>在释放函数里，添加Agent::Unregister&lt;***&gt;()用于释放类型的注册信息。</li>
</ul>
<p>如下代码样例所示：</p>
<div class="highlighter-rouge">
<pre class="highlight"><code>
<span class="n">bool</span> <span class="nf">InitBehavic</span><span class="p">(</span><span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">EFileFormat</span> <span class="n">ff</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Config</span><span class="o">::</span><span class="n">SetSocketBlocking</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Config</span><span class="o">::</span><span class="n">SetSocketPort</span><span class="p">(</span><span class="mi">8081</span><span class="p">);</span>

    <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">Register</span><span class="o">&lt;</span><span class="n">CBTPlayer</span><span class="o">&gt;</span><span class="p">();</span>

    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">SetFilePath</span><span class="p">(</span><span class="s">"../test/demo_running/behaviac/exported"</span><span class="p">);</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">SetFileFormat</span><span class="p">(</span><span class="n">ff</span><span class="p">);</span>

    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">ExportMetas</span><span class="p">(</span><span class="s">"../test/demo_running/behaviac/demo_running.xml"</span><span class="p">);</span>

    <span class="c1">//behaviac::Agent::SetIdMask(kIdMask_Wolrd | kIdMask_Opponent);
</span>    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">SetDeltaFrames</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>

    <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">CleanupBehaviac</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">UnRegister</span><span class="o">&lt;</span><span class="n">CBTPlayer</span><span class="o">&gt;</span><span class="p">();</span>
<span class="n">    behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">Cleanup</span><span class="p">();</span>
<span class="p">}</span>

</code></pre>
</div>
<p>更多细节可以参考behaviac组件C++源码中附带的test/demo_running工程的<a href="https://github.com/Tencent/behaviac/blob/master/test/demo_running/demo_running.cpp">demo_running.cpp</a>文件。</p>
]]></content:encoded>
					
					<wfw:commentRss>/tutorial3_1_meta_cpp_register/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>C#运行时端中元信息的注册和导出</title>
		<link>/tutorial3_2_meta_cs_register/</link>
					<comments>/tutorial3_2_meta_cs_register/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:25:57 +0000</pubDate>
				<category><![CDATA[3.5]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[运行时]]></category>
		<guid isPermaLink="false">/?p=278</guid>

					<description><![CDATA[behaviac组件的基本运作机制就是在运行时端（C#）和编辑器通过元信息进行交互，如图1所示。其中，元信息里面包含了类自身的描述、属性、方法及类的实例等。 图<a class="moretag" href="/tutorial3_2_meta_cs_register/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<p id="c-">behaviac组件的基本运作机制就是在运行时端（C#）和编辑器通过元信息进行交互，如图1所示。其中，元信息里面包含了类自身的描述、属性、方法及类的实例等。</p>
<p><img class="aligncenter" src="/img/overview/meta.png" alt="" /></p>
<p style="text-align: center;">图1 基于元信息的编辑器和运行时端的交互</p>
<p>在运行时端，也即游戏代码端，通过注册（C#通过标记Attribute的方式）并导出供行为树引擎和编辑器使用的XML元信息。运行时端主要是由程序员编写Agent的子类及其属性和方法，然后调用相关接口将这些元信息导出，就可以在编辑器中对这些元信息进行使用。</p>
<p>在编辑器中也可以创建和编辑元信息。在项目开始初期，也就是程序员还没把代码写出来之前，策划就可以自己手动的创建一些Agent子类、属性和方法等元信息。这样可以加速游戏原型的创建，也就是策划不用等程序员，就可以进行游戏原型的编辑。</p>
<p>整个工作流程主要分为以下几个步骤：</p>
<h3 id="section">1 注册元信息</h3>
<p>C#中编写的游戏类从behaviac.Agent派生，并通过相关的Attribute来标记元信息：</p>
<ul>
<li>类：TypeMetaInfo</li>
<li>成员属性：MemberMetaInfo</li>
<li>成员方法：MethodMetaInfo</li>
</ul>
<p>这3个类都可以接受诸如显示名字，描述等更多参数。详细请参考代码。</p>
<p>如下代码样例所示：</p>
<figure class="highlight">
<pre><code class="language-cs" data-lang="cs"><span class="na">[behaviac.TypeMetaInfo()]</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">AgentNodeTest</span> <span class="p">:</span> <span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span>
<span class="p">{</span>
    <span class="p">[</span><span class="n">behaviac</span><span class="p">.</span><span class="nf">MemberMetaInfo</span><span class="p">()]</span>
    <span class="k">public</span> <span class="kt">int</span> <span class="n">testVar_0</span> <span class="p">=</span> <span class="p">-</span><span class="m">1</span><span class="p">;</span>

    <span class="p">[</span><span class="n">behaviac</span><span class="p">.</span><span class="nf">MemberMetaInfo</span><span class="p">(</span><span class="s">"testVar_1"</span><span class="p">,</span> <span class="s">"testVar_1 property"</span><span class="p">,</span> <span class="m">100</span><span class="p">)]</span>
    <span class="k">public</span> <span class="kt">int</span> <span class="n">testVar_1</span> <span class="p">=</span> <span class="p">-</span><span class="m">1</span><span class="p">;</span>

    <span class="p">[</span><span class="n">behaviac</span><span class="p">.</span><span class="nf">MemberMetaInfo</span><span class="p">()]</span>
    <span class="k">public</span> <span class="kt">float</span> <span class="n">testVar_2</span> <span class="p">=</span> <span class="p">-</span><span class="m">1.0f</span><span class="p">;</span>

    <span class="p">[</span><span class="n">behaviac</span><span class="p">.</span><span class="nf">MemberMetaInfo</span><span class="p">()]</span>
    <span class="k">public</span> <span class="kt">int</span> <span class="n">waiting_timeout_interval</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>

    <span class="p">[</span><span class="n">behaviac</span><span class="p">.</span><span class="nf">MemberMetaInfo</span><span class="p">()]</span>
    <span class="k">public</span> <span class="kt">string</span> <span class="n">testVar_str_0</span> <span class="p">=</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>

    <span class="k">public</span> <span class="kt">bool</span> <span class="n">m_bCanSee</span> <span class="p">=</span> <span class="k">false</span><span class="p">;</span>

    <span class="p">[</span><span class="n">behaviac</span><span class="p">.</span><span class="nf">MethodMetaInfo</span><span class="p">()]</span>
    <span class="k">public</span> <span class="k">void</span> <span class="nf">setEventVarInt</span><span class="p">(</span><span class="kt">int</span> <span class="n">var</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">event_test_var_int</span> <span class="p">=</span> <span class="n">var</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="p">[</span><span class="n">behaviac</span><span class="p">.</span><span class="nf">MethodMetaInfo</span><span class="p">()]</span>
    <span class="k">public</span> <span class="k">void</span> <span class="nf">setEventVarBool</span><span class="p">(</span><span class="kt">bool</span> <span class="n">var</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">event_test_var_bool</span> <span class="p">=</span> <span class="n">var</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>
<h3 id="section-1">2 导出元信息</h3>
<p>由于C#代码中已经包含了各种Attribute来描述元信息，因而导出相比C++要简单：</p>
<ul>
<li>Agent子类的实例通过Agent.RegisterInstanceName&lt;***&gt;(…)来进行注册。</li>
<li>调用Workspace.Instance.FilePath设置元信息文件导出的位置。</li>
<li>调用Workspace.Instance.ExportMetas(…)导出元信息文件。</li>
</ul>
<p>如下代码样例所示：</p>
<figure class="highlight">
<pre><code class="language-cs" data-lang="cs"><span class="k">public</span> <span class="kt">bool</span> <span class="nf">Init</span> <span class="p">()</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">ms_fileSystem</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">ms_fileSystem</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">BehaviacFileManager</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="c1">//&lt; write log file
</span>    <span class="n">behaviac</span><span class="p">.</span><span class="n">Config</span><span class="p">.</span><span class="n">IsLogging</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span>
    <span class="c1">//behaviac.Config.IsSocketing = false;
</span>
    <span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">Instance</span><span class="p">.</span><span class="n">FilePath</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">WorkspaceExportPath</span><span class="p">;</span>
    <span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">Instance</span><span class="p">.</span><span class="n">FileFormat</span> <span class="p">=</span> <span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">EFileFormat</span><span class="p">.</span><span class="n">EFF_xml</span><span class="p">;</span>

    <span class="c1">//register names
</span>    <span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="n">RegisterInstanceName</span><span class="p">&lt;</span><span class="n">GameLevelCommon</span><span class="p">&gt;(</span><span class="s">"GameLevel"</span><span class="p">);</span>
    <span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">Instance</span><span class="p">.</span><span class="nf">ExportMetas</span><span class="p">(</span><span class="s">"behaviac/workspace/xmlmeta/BattleCityMeta.xml"</span><span class="p">);</span>

    <span class="n">behaviac</span><span class="p">.</span><span class="n">Debug</span><span class="p">.</span><span class="nf">Log</span><span class="p">(</span><span class="s">"Behaviac meta data export over."</span><span class="p">);</span>
    <span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="nf">SetIdMask</span><span class="p">(</span><span class="m">0xffffffff</span><span class="p">);</span>

    <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">void</span> <span class="nf">Uninit</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">Instance</span><span class="p">.</span><span class="nf">Cleanup</span><span class="p">();</span>
<span class="p">}</span></code></pre>
</figure>
<p>更多细节可以参考behaviac组件C#源码中附带的integration/BattleCityDemo工程的<a href="https://github.com/Tencent/behaviac/blob/master/integration/BattleCityDemo/Assets/Scripts/BehaviacSystem.cs">BehaviacSystem.cs</a>文件。</p>
]]></content:encoded>
					
					<wfw:commentRss>/tutorial3_2_meta_cs_register/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>导出和使用C#行为树</title>
		<link>/tutorial4_3_export_cs/</link>
					<comments>/tutorial4_3_export_cs/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:29:49 +0000</pubDate>
				<category><![CDATA[3.5]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[编辑器]]></category>
		<guid isPermaLink="false">/?p=286</guid>

					<description><![CDATA[在“导出行为树”对话框中，选择“C# Behavior Exporter”，如下图所示： 点击上图中右侧的“…”设置按钮，在弹出的“C#导出设置”对话框中设置导<a class="moretag" href="/tutorial4_3_export_cs/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<ul>
<li>在“导出行为树”对话框中，选择“C# Behavior Exporter”，如下图所示：</li>
</ul>
<p><img class="aligncenter" src="/img/tutorials/tutorial4/exportCs.png" alt="" /></p>
<ul>
<li>点击上图中右侧的“…”设置按钮，在弹出的“C#导出设置”对话框中设置导出文件所在的位置，如图2所示：</li>
</ul>
<p><img class="aligncenter" src="/img/tutorials/tutorial4/csExportSettings.png" alt="" /></p>
<ul>
<li>回到“导出行为树”对话框，点击“导出”按钮，开始导出<code class="highlighter-rouge">C#</code>文件。在指定的导出位置（默认为当前工作区的导出路径）会自动生成一个名为<code class="highlighter-rouge">behaviac_generated</code>的文件夹，里面生成了<code class="highlighter-rouge">behaviors</code>和<code class="highlighter-rouge">types</code>两个子文件夹，如图3所示：<img class="aligncenter" src="/img/tutorials/tutorial4/exportedCsFiles.png" alt="" /></li>
<li><code class="highlighter-rouge">behaviors</code>文件夹含有<code class="highlighter-rouge">generated_behaviors.cs</code>及其他单个的行为树<code class="highlighter-rouge">.cs</code>文件（如果没有勾选“导出统一文件？”，则对每一棵行为树都会生成独立的<code class="highlighter-rouge">.cs</code>文件）。</li>
<li><code class="highlighter-rouge">types</code>文件夹中含有<code class="highlighter-rouge">agentproperties.cs</code>（为<code class="highlighter-rouge">Agent</code>类自定义的属性和方法，会扩展在该文件中）、<code class="highlighter-rouge">customizedtypes.cs</code>（自定义的枚举和结构体类型，会生成在这个文件中）以及其他的<code class="highlighter-rouge">Agent</code>子类的文件（这些文件是为添加的<code class="highlighter-rouge">Agent</code>子类自动生成的<code class="highlighter-rouge">.cs</code>文件，需要程序员补充代码进一步实现这些<code class="highlighter-rouge">Agent</code>子类的逻辑），这些自动生成的文件都需要包含到自己的游戏项目中。</li>
</ul>
<ul>
<li>注意：这些自动生成的文件都需要包含到自己的游戏项目中，一起参与整个项目代码的编译和构建。</li>
<li>在项目中包含了这些自动生成的<code class="highlighter-rouge">.cs</code>文件后，就可以与前面提及的<a href="/docs/zh/tutorials/tutorial4_1_export_xml_bson/">导出和使用XML/BSON行为树</a>一样的接口和方式加载使用这些文件，只是需要将文件格式改为<code class="highlighter-rouge">EFF_cs</code>：</li>
</ul>
<figure class="highlight">
<pre><code class="language-cs" data-lang="cs"><span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">Instance</span><span class="p">.</span><span class="n">FileFormat</span> <span class="p">=</span> <span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">EFileFormat</span><span class="p">.</span><span class="n">EF</span></code></pre>
</figure>
]]></content:encoded>
					
					<wfw:commentRss>/tutorial4_3_export_cs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>导出和使用XML/BSON行为树</title>
		<link>/tutorial4_1_export_xml_bson/</link>
					<comments>/tutorial4_1_export_xml_bson/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:27:46 +0000</pubDate>
				<category><![CDATA[3.5]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[运行时]]></category>
		<guid isPermaLink="false">/?p=282</guid>

					<description><![CDATA[目前behaviac组件支持4种文件格式（XML、BSON、C++和C#）行为树的导出。在项目开发过程中，建议使用XML格式的导出文件，以便于调试和查错等；而在<a class="moretag" href="/tutorial4_1_export_xml_bson/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<p id="section">目前behaviac组件支持4种文件格式（XML、BSON、C++和C#）行为树的导出。在项目开发过程中，建议使用XML格式的导出文件，以便于调试和查错等；而在最终的发布（release）版本中，可以导出C++或C#格式的行为树文件，以便提高运行效率。</p>
<h3 id="xmlbson">导出和使用XML/BSON行为树</h3>
<ul>
<li>在编辑器中导出整个工作区文件，在“导出行为树”对话框中，勾选“Xml Behavior Exporter”或“Bson Behavior Exporter”，如下图所示：</li>
</ul>
<p><img class="aligncenter" src="/img/tutorials/tutorial4/exportXMLBson.png" alt="" /></p>
<ul>
<li>导出行为树文件结束后，回到运行时（游戏）代码端，按以下步骤使用行为树文件：
<ul>
<li>在游戏的初始化函数中，添加Agent::Register&lt;***&gt;()注册类信息到引擎库中。</li>
<li>调用Workspace::SetFilePath(…)函数，设置行为树文件的加载路径，也即编辑器导出行为树文件所在的目录。</li>
<li>调用Workspace::SetFileFormat(…)函数，设置加载行为树的文件格式，如果不调用则默认加载EFF_xml格式。</li>
<li>通过调用Agent的接口btload(…)加载所需的行为树文件。</li>
<li>通过调用Agent的接口btsetcurrent(…)设置当前准备执行的行为树文件。</li>
<li>行为树的更新执行流程请参考<a href="/docs/zh/tutorials/tutorial13_updateloop/">更新流程</a>。</li>
<li>在游戏的释放函数里面，添加Agent::Unregister&lt;***&gt;()用于释放类型的注册信息。</li>
</ul>
</li>
</ul>
<p>如下代码样例所示：</p>
<div class="highlighter-rouge">
<pre class="highlight"><code>
<span class="n">bool</span> <span class="nf">InitBehavic</span><span class="p">(</span><span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">EFileFormat</span> <span class="n">ff</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Config</span><span class="o">::</span><span class="n">SetSocketBlocking</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Config</span><span class="o">::</span><span class="n">SetSocketPort</span><span class="p">(</span><span class="mi">8081</span><span class="p">);</span>

    <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">Register</span><span class="o">&lt;</span><span class="n">CBTPlayer</span><span class="o">&gt;</span><span class="p">();</span>

    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">SetFilePath</span><span class="p">(</span><span class="s">"../test/demo_running/behaviac/exported"</span><span class="p">);</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">SetFileFormat</span><span class="p">(</span><span class="n">ff</span><span class="p">);</span>

    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">ExportMetas</span><span class="p">(</span><span class="s">"../test/demo_running/behaviac/demo_running.xml"</span><span class="p">);</span>

    <span class="c1">//behaviac::Agent::SetIdMask(kIdMask_Wolrd | kIdMask_Opponent);
</span>    <span class="n">behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">SetDeltaFrames</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>

    <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">bool</span> <span class="nf">InitPlayer</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">pszTreeName</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">g_player</span> <span class="o">=</span> <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">Create</span><span class="o">&lt;</span><span class="n">CBTPlayer</span><span class="o">&gt;</span><span class="p">();</span>

    <span class="n">bool</span> <span class="n">bRet</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
    <span class="n">bRet</span> <span class="o">=</span> <span class="n">g_player</span><span class="o">-&gt;</span><span class="n">btload</span><span class="p">(</span><span class="n">pszTreeName</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="n">bRet</span><span class="p">);</span>

    <span class="n">g_player</span><span class="o">-&gt;</span><span class="n">btsetcurrent</span><span class="p">(</span><span class="n">pszTreeName</span><span class="p">);</span>

    <span class="k">return</span> <span class="n">bRet</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">CleanupPlayer</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">Destroy</span><span class="p">(</span><span class="n">g_player</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">CleanupBehaviac</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">UnRegister</span><span class="o">&lt;</span><span class="n">CBTPlayer</span><span class="o">&gt;</span><span class="p">();</span>

<span class="n">    behaviac</span><span class="o">::</span><span class="n">Workspace</span><span class="o">::</span><span class="n">GetInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">Cleanup</span><span class="p">();</span>
<span class="p">}</span>

</code></pre>
</div>
<p>总之，一棵行为树的加载到执行，关键的就是前面提及的三个接口：btload()、btsetcurrent()和btexec()。</p>
<p>更多细节可以参考behaviac组件C++源码中附带的test/demo_running工程的<a href="https://github.com/Tencent/behaviac/blob/master/test/demo_running/demo_running.cpp">demo_running.cpp</a>文件。</p>
<p>类似的，对于C#版的运行时端，采用如下代码样例加载使用刚才导出的行为树：</p>
<figure class="highlight">
<pre><code class="language-cs" data-lang="cs"><span class="k">public</span> <span class="kt">bool</span> <span class="nf">Init</span> <span class="p">()</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">ms_fileSystem</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">ms_fileSystem</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">BehaviacFileManager</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="c1">//&lt; write log file
</span>    <span class="n">behaviac</span><span class="p">.</span><span class="n">Config</span><span class="p">.</span><span class="n">IsLogging</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span>
    <span class="c1">//behaviac.Config.IsSocketing = false;
</span>
    <span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">Instance</span><span class="p">.</span><span class="n">FilePath</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">WorkspaceExportPath</span><span class="p">;</span>
    <span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">Instance</span><span class="p">.</span><span class="n">FileFormat</span> <span class="p">=</span> <span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">EFileFormat</span><span class="p">.</span><span class="n">EFF_xml</span><span class="p">;</span>

    <span class="c1">//register names
</span>    <span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="n">RegisterInstanceName</span><span class="p">&lt;</span><span class="n">GameLevelCommon</span><span class="p">&gt;(</span><span class="s">"GameLevel"</span><span class="p">);</span>
    <span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">Instance</span><span class="p">.</span><span class="nf">ExportMetas</span><span class="p">(</span><span class="s">"behaviac/workspace/xmlmeta/BattleCityMeta.xml"</span><span class="p">);</span>

    <span class="n">behaviac</span><span class="p">.</span><span class="n">Debug</span><span class="p">.</span><span class="nf">Log</span><span class="p">(</span><span class="s">"Behaviac meta data export over."</span><span class="p">);</span>
    <span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="nf">SetIdMask</span><span class="p">(</span><span class="m">0xffffffff</span><span class="p">);</span>

    <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">void</span> <span class="nf">Uninit</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">behaviac</span><span class="p">.</span><span class="n">Workspace</span><span class="p">.</span><span class="n">Instance</span><span class="p">.</span><span class="nf">Cleanup</span><span class="p">();</span>
<span class="p">}</span>

<span class="c1">// 加载所需的行为树文件
</span><span class="k">if</span><span class="p">(</span><span class="n">behaviorTree</span><span class="p">.</span><span class="n">Length</span> <span class="p">&gt;</span> <span class="m">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">    btloadResult</span> <span class="p">=</span> agent.<span class="nf">btload</span><span class="p">(</span><span class="n">behaviorTree</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
<span class="k">    if</span><span class="p">(</span><span class="n">btloadResult</span><span class="p">)</span>
        agent.<span class="nf">btsetcurrent</span><span class="p">(</span><span class="n">behaviorTree</span><span class="p">);</span>
<span class="k">    else</span>
        <span class="n">Debug</span><span class="p">.</span><span class="nf">LogError</span><span class="p">(</span><span class="s">"Behavior tree data load failed! "</span> <span class="p">+ </span><span class="n">behaviorTree</span><span class="p">);</span>
<span class="p">}</span></code></pre>
</figure>
<p>更多细节可以参考behaviac组件C#源码中附带的integration/BattleCityDemo工程的<a href="https://github.com/Tencent/behaviac/blob/master/integration/BattleCityDemo/Assets/Scripts/BehaviacSystem.cs">BehaviacSystem.cs</a>文件。</p>
]]></content:encoded>
					
					<wfw:commentRss>/tutorial4_1_export_xml_bson/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Agent实例的用法</title>
		<link>/instance/</link>
					<comments>/instance/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:44:53 +0000</pubDate>
				<category><![CDATA[3.5]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[概念]]></category>
		<guid isPermaLink="false">/?p=313</guid>

					<description><![CDATA[在编辑器的节点属性窗口中，为了给某个节点选择和配置属性，首先需要选择一个实例（instance），然后再选择该实例的属性或方法，如下图所示： 这些实例主要来自于<a class="moretag" href="/instance/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<p>在编辑器的节点属性窗口中，为了给某个节点选择和配置属性，首先需要选择一个实例（instance），然后再选择该实例的属性或方法，如下图所示：</p>
<p><img class="aligncenter" src="/img/tutorials/tutorial17/instance_list.png" alt="" /></p>
<p>这些实例主要来自于如下三个方面：</p>
<ul>
<li>Self：表示当前行为树根节点所配置的Agent类型的实例，类似于程序语言中的this。</li>
<li>成员实例：当前行为树根节点所配置的Agent类型的成员属性、自定义属性或局部变量，也是Agent或其子类类型。</li>
<li>全局实例：运行时端（游戏端）注册和导出的各种Agent或其子类的全局实例。</li>
</ul>
<p>其中，成员实例无需编写额外代码来进行注册和导出，behaviac组件会自动根据当前行为树根节点所配置的Agent类型，列举出所有的成员实例以供选择。但在使用该成员实例之前，需要确保该实例已经赋过值，不是空指针/引用。</p>
<p>对于全局实例，在运行时端（游戏端）的各种Agent或其子类实例的名字注册和绑定的设计意图，主要是为了支持单件（Singleton）或者类似确定的全局性的实例（同一个类可能会有若干个实例而不是仅仅有一个实例），例如：player，camera，director等。</p>
<p>注意：只有通过RegisterInstanceName注册过的“名字”才在导出元信息时被导出；而BindInstance和Create等与实例相关的函数在执行行为树的时候才需要，如果只是导出元信息则不需要。</p>
<h3 id="c">C++中全局实例的注册</h3>
<p>Agent::RegisterInstanceName可以注册一个名字，该名字表示游戏中某个Agent类的实例，如下代码所示：</p>
<div class="highlighter-rouge">
<pre class="highlight"><code>
<span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">RegisterInstanceName</span><span class="o">&lt;</span><span class="n">AgentNodeTest</span><span class="o">&gt;</span><span class="p">();</span>
<span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">RegisterInstanceName</span><span class="o">&lt;</span><span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">&gt;</span><span class="p">(</span><span class="s">"Name_Agent_0"</span><span class="p">);</span>

</code></pre>
</div>
<p>需要说明的是，游戏中需要调用Agent::Create或Agent::BindInstance创建实例并且绑定到该名字。如果指定的名字没有注册或注册的类型不同或该名字已经绑定，则调用Agent::Create的时候会有runtime的错误。</p>
<p>当调用Agent::RegisterInstanceName和Agent::Create而没有指定名字的时候，该Agent类型的名字将作为实例的名字被注册和绑定，如下代码所示：</p>
<div class="highlighter-rouge">
<pre class="highlight"><code>
<span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">*</span> <span class="n">testAgentA</span> <span class="o">=</span> <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">Create</span><span class="o">&lt;</span><span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">&gt;</span><span class="p">(</span><span class="s">"Name_Agent_0"</span><span class="p">);</span>
<span class="n">AgentNodeTest</span><span class="o">*</span> <span class="n">testAgentB</span> <span class="o">=</span> <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">Create</span><span class="o">&lt;</span><span class="n">AgentNodeTest</span><span class="o">&gt;</span><span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>

<span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">*</span> <span class="n">testAgent_0</span> <span class="o">=</span> <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">GetInstance</span><span class="o">&lt;</span><span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">&gt;</span><span class="p">(</span><span class="s">"Name_Agent_0"</span><span class="p">);</span>
<span class="n">AgentNodeTest</span><span class="o">*</span> <span class="n">testAgent_1</span> <span class="o">=</span> <span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">GetInstance</span><span class="o">&lt;</span><span class="n">AgentNodeTest</span><span class="o">&gt;</span><span class="p">();</span>

<span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">BindInstance</span><span class="p">(</span><span class="n">testAgent_0</span><span class="p">,</span> <span class="s">"Name_Agent_0"</span><span class="p">);</span>
<span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">BindInstance</span><span class="p">(</span><span class="n">testAgent_1</span><span class="p">,</span> <span class="err">“</span><span class="n">AgentNodeTest</span><span class="err">”</span><span class="p">);</span>

<span class="n">CHECK_EQUAL</span><span class="p">(</span><span class="n">testAgent_0</span><span class="p">,</span> <span class="n">testAgentA</span><span class="p">);</span>
<span class="n">CHECK_EQUAL</span><span class="p">(</span><span class="n">testAgent_1</span><span class="p">,</span> <span class="n">testAgentB</span><span class="p">);</span>

<span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">UnbindInstance</span><span class="p">(</span><span class="s">"Name_Agent_0"</span><span class="p">);</span>
<span class="n">behaviac</span><span class="o">::</span><span class="n">Agent</span><span class="o">::</span><span class="n">UnbindInstance</span><span class="p">(</span><span class="s">"AgentNodeTest"</span><span class="p">);</span>

</code></pre>
</div>
<p>更多细节可以参考behaviac组件C++源码中附带的test工程的<a href="https://github.com/Tencent/behaviac/blob/master/test/btunittest/Others/btloadtest.cpp">btloadtest.cpp</a>文件。</p>
<h3 id="c-">C# 中全局实例的注册</h3>
<p>类似的，在C#中实例的注册和绑定相关代码如下：</p>
<pre><span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="n">RegisterInstanceName</span><span class="p">&lt;</span><span class="n">AgentNodeTest</span><span class="p">&gt;();</span> <span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="n">RegisterInstanceName</span><span class="p">&lt;</span><span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">&gt;(</span><span class="s">"Name_Agent_0"</span><span class="p">);</span> 

<span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="nf">BindInstance</span><span class="p">(</span><span class="n">parTestAgent</span><span class="p">,</span> <span class="s">"Name_Agent_0"</span><span class="p">);</span> <span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="nf">BindInstance</span><span class="p">(</span><span class="n">nodeTestAgent</span><span class="p">,</span> <span class="s">"AgentNodeTest"</span><span class="p">);

</span><span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span> <span class="n">testAgent_0</span> <span class="p">=</span> <span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="n">GetInstance</span><span class="p">&lt;</span><span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">&gt;(</span><span class="s">"Name_Agent_0"</span><span class="p">);
</span><span class="n">AgentNodeTest</span> <span class="n">testAgent_1</span> <span class="p">=</span> <span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="n">GetInstance</span><span class="p">&lt;</span><span class="n">AgentNodeTest</span><span class="p">&gt;();</span> 
<span class="n">AgentNodeTest</span> <span class="n">testAgent_3</span> <span class="p">=</span> <span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="nf">GetAgent</span><span class="p">(</span><span class="s">"AgentNodeTest"</span><span class="p">)</span> <span class="k">as</span> <span class="n">AgentNodeTest</span><span class="p">;

</span><span class="n">Assert</span><span class="p">.</span><span class="nf">AreEqual</span><span class="p">(</span><span class="n">testAgent_0</span><span class="p">,</span> <span class="n">parTestAgent</span><span class="p">);
</span><span class="n">Assert</span><span class="p">.</span><span class="nf">AreEqual</span><span class="p">(</span><span class="n">testAgent_1</span><span class="p">,</span> <span class="n">nodeTestAgent</span><span class="p">);
</span><span class="n">Assert</span><span class="p">.</span><span class="nf">AreEqual</span><span class="p">(</span><span class="n">testAgent_1</span><span class="p">,</span> <span class="n">testAgent_3</span><span class="p">);

</span><span class="n">Assert</span><span class="p">.</span><span class="nf">NotNull</span><span class="p">(</span><span class="n">testAgent_0</span><span class="p">);
</span><span class="n">Assert</span><span class="p">.</span><span class="nf">NotNull</span><span class="p">(</span><span class="n">testAgent_1</span><span class="p">);

</span><span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="nf">UnbindInstance</span><span class="p">(</span><span class="s">"Name_Agent_0"</span><span class="p">);
</span><span class="n">behaviac</span><span class="p">.</span><span class="n">Agent</span><span class="p">.</span><span class="nf">UnbindInstance</span><span class="p">(</span><span class="s">"AgentNodeTest"</span><span class="p">);</span></pre>
<p>更多细节可以参考behaviac组件C#源码中附带的integration/unity工程的<a href="https://github.com/Tencent/behaviac/blob/master/integration/unity/Assets/Scripts/behaviac/BehaviacUnitTest/Editor/ParUnitTest/OtherUnitTest.cs">OtherUnitTest.cs</a>文件。</p>
<div class="section-nav"></div>
]]></content:encoded>
					
					<wfw:commentRss>/instance/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>运行时端的执行流程</title>
		<link>/tutorial13_updateloop/</link>
					<comments>/tutorial13_updateloop/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:42:05 +0000</pubDate>
				<category><![CDATA[文章]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[C++]]></category>
		<guid isPermaLink="false">/?p=306</guid>

					<description><![CDATA[在运行时端（下面以C++版来加以说明，C#版基本类似），整个组建的更新可以通过Workspace::Update()函数来执行，该函数主要包括两大功能： 调用D<a class="moretag" href="/tutorial13_updateloop/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<p id="section">在运行时端（下面以C++版来加以说明，C#版基本类似），整个组建的更新可以通过Workspace::Update()函数来执行，该函数主要包括两大功能：</p>
<ul>
<li>调用DebugUpdate()函数来更新一些连调和热加载相关的功能。</li>
<li>根据m_bExecAgents来判断是否需要执行所有Agent实例的btexec()函数，可以通过接口Workspace::SetIsExecAgents(bool bExecAgents)对m_bExecAgents进行设置。</li>
</ul>
<p>具体执行逻辑如下代码所示：</p>
<div class="highlighter-rouge">
<pre class="highlight"><code><span class="kt">void</span> <span class="n">Workspace</span><span class="o">::</span><span class="n">DebugUpdate</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">    this</span><span class="o">-&gt;</span><span class="n">LogFrames</span><span class="p">();</span>
<span class="k">    this</span><span class="o">-&gt;</span><span class="n">HandleRequests</span><span class="p">();</span>

<span class="k">    if</span> <span class="p">(</span><span class="k">this</span><span class="o">-&gt;</span><span class="n">GetAutoHotReload</span><span class="p">())</span>
<span class="p">    {</span>
<span class="k">        this</span><span class="o">-&gt;</span><span class="n">HotReload</span><span class="p">();</span>
<span class="p">    }</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="n">Workspace</span><span class="o">::</span><span class="n">Update</span><span class="p">()</span>
<span class="p">{
</span><span class="k">    this</span><span class="o">-&gt;</span><span class="n">DebugUpdate</span><span class="p">();</span>

    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="o">-&gt;</span><span class="n">m_bExecAgents</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="kt">int</span> <span class="n">contextId</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>

        <span class="n">Context</span><span class="o">::</span><span class="n">execAgents</span><span class="p">(</span><span class="n">contextId</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>对于C++版，行为树的执行可以调用behaviac::Workspace::GetInstance()-&gt;Update()来执行所有Agent实例的行为树，也可以单独调用Agent的接口btexec()来执行单个实例的行为树。</p>
<p>其中，Workspace::Update()会遍历所有的Agent实例并依次执行btexec()，但在自己的游戏项目中，可能在一帧中需要对某些Agent多次调用btexec()，而另一些Agent只需调用一次，这时候就需要单独调用Agent::btexec()，而不是统一调用Workspace::Update()。</p>
<p>Workspace::Update()在调用Agent::btexec()之前，会检查Agent::IsActive()是否为true，如果为false，那么btexec()就不会被调用。</p>
<p>此外，为了支持连调和热加载，请务必保证在自己游戏的更新函数中调用了DebugUpdate()函数。如果已经调用了behaviac::Workspace::GetInstance()-&gt;Update()，那么就不需要再单独调用DebugUpdate()。</p>
<p>上述示例代码虽然是C++，但对于C#，也都是同名的。</p>
<p>特别注意：对于C#版，behaviac.Workspace.IsExecAgents默认设为false。</p>
<ul>
<li>如果将behaviac.Workspace.IsExecAgents设为true，使用behaviac.Workspace.Instance.Update()集中进行更新，Agent自己的更新就不需要调用btexec()了。</li>
<li>如果将behaviac.Workspace.IsExecAgents设为false，则不使用behaviac.Workspace.Instance.Update()集中进行更新，Agent自己的更新就需要调用btexec()了。</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>/tutorial13_updateloop/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>元信息的使用和编辑</title>
		<link>/tutorial3_3_meta_edit/</link>
					<comments>/tutorial3_3_meta_edit/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 13 May 2016 02:26:41 +0000</pubDate>
				<category><![CDATA[3.5]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[编辑器]]></category>
		<guid isPermaLink="false">/?p=280</guid>

					<description><![CDATA[使用元信息 在编辑器中新建一个工作区，并根据上一步中导出的元数据文件所在的文件夹，设置该工作区的“元数据位置”，可以看到demo_running.xml文件已经<a class="moretag" href="/tutorial3_3_meta_edit/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<h2>使用元信息</h2>
<ul>
<li>在编辑器中新建一个工作区，并根据上一步中导出的元数据文件所在的文件夹，设置该工作区的“元数据位置”，可以看到demo_running.xml文件已经可以使用，如下图所示：</li>
</ul>
<p><img class="aligncenter" src="/img/tutorials/tutorial3/editWorkspace.png" alt="" /></p>
<ul>
<li>新建行为树文件，并为该行为树添加一些节点，选择某个节点后，可以设置该节点的属性（可选属性正是来至上面导出的元信息），如下图所示：</li>
</ul>
<p><img class="aligncenter" src="/img/overview/action.png" alt="" /></p>
<h2>编辑元信息</h2>
<ul>
<li>前面介绍的是在运行时（游戏）端编写代码导出元信息到编辑器中，behaviac组件也支持在编辑器中创建和编辑元信息。</li>
<li>在编辑器中，通过菜单项“视图”-&gt;“元信息浏览”（或快捷键Ctrl+M）打开元信息浏览器，如下图所示：</li>
</ul>
<p><img class="aligncenter" src="/img/overview/metabrowser.png" alt="" /></p>
<ul>
<li>类型列表：左上方的“类型列表”显示了所有的Agent类、自定义的枚举和结构体类型，其右侧是当前选中的类型的属性。“类型列表”中的名字前面带有“*”，表示该类型是在编辑器中创建出来的。创建一个类型（Agent类、枚举或结构体），可以点击元信息浏览器右上角的“新增”按钮，如下图所示。后文将提到对这些新增的类型，导出时会自动生成相应的C++或C#源码文件，这样程序员就可以在生成的源码文件基础上添加和实现自己的游戏逻辑。</li>
</ul>
<p><img class="aligncenter" src="/img/tutorials/tutorial3/newType.png" alt="" /></p>
<ul>
<li>实例名称：元信息浏览器中的“实例名称”，用于列出当前选中的Agent类型的所有实例，这些实例是通过之前提及的Agent::RegisterInstanceName接口在运行时端注册并导出的。如果当前选中的Agent类型没有导出任何实例，那么这一行显示为空白。</li>
<li>成员类型：成员类型包括属性（Property）、方法（Method）和任务（Task）。</li>
<li>成员列表：选中了上面的“成员类型”后，会列出当前选中的类型的所有成员属性、方法或任务。如果是自定义的成员，那么在列表中的名字前会多出一个“*”。点击“成员列表”右侧的“新增”按钮，可以新增一个成员，可以通过选中“是否局部变量”，将该变量标记为局部变量（在列表中的名字前会多出一个“-”），如下图所示。新增一个方法或任务也类似。选中某个成员后，在元信息浏览器下方会列出该成员的所有属性。</li>
</ul>
<p><img class="aligncenter" src="/img/tutorials/tutorial3/newProperty.png" alt="" /></p>
<p>只要在元信息浏览器中编辑了元信息，那么点击元信息浏览器下方的“应用”或“确认”按钮后，编辑器就会在工作区源文件所在目录的保存出一个名为“behaviac.bb.xml”的文件，如下图所示：</p>
<p><img class="aligncenter" src="/img/tutorials/tutorial3/bbFile.png" alt="" /></p>
<p>后文我们将介绍，这个“behaviac.bb.xml”文件也会跟其他行为树源文件一并导出给运行时库。</p>
]]></content:encoded>
					
					<wfw:commentRss>/tutorial3_3_meta_edit/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>运行时端常用类的介绍</title>
		<link>/basic_classes/</link>
					<comments>/basic_classes/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 11 Apr 2016 09:49:47 +0000</pubDate>
				<category><![CDATA[文章]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[运行时]]></category>
		<guid isPermaLink="false">/?p=152</guid>

					<description><![CDATA[在使用behaviac运行时端（Runtime）的源代码或API时，有几个最常用的类值得注意：如Workspace、Agent、Config等。 Workspa<a class="moretag" href="/basic_classes/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<p>在使用behaviac运行时端（Runtime）的源代码或API时，有几个最常用的类值得注意：如Workspace、Agent、Config等。</p>
<h3>Workspace类</h3>
<p>Workspace类主要用于管理类型信息的导出，加载、卸载、执行、停止执行行为树，设置时间和帧数等。</p>
<ul>
<li>GetInstance() ：用于获取Workspace的单件实例。</li>
<li>ExportMetas(const char*) ：导出类型信息文件到指定的路径，详见文档《<a href="{{site.url}}{{site.baseurl}}/docs/zh/tutorials/tutorial3_1_meta_cpp_register/">C++运行时端中类型信息的注册和导出</a>》。</li>
<li>SetFilePath(const char*) ：用于加载行为树时指定行为树文件所在的目录。</li>
<li>SetFileFormat(EFileFormat) ：用于指定加载行为树文件的格式，包括Xml、Bson、Cpp/Cs、Default。其中Default表示先尝试加载Xml格式，如果找不到再尝试加载Bson格式，最后尝试加载Cpp/Cs格式，这个功能可用于行为树的热更新。</li>
<li>Update() ：用于执行所有Agent的当前行为树，行为树的执行也可以不通过该API，可以自己单独调用Agent的btexec()方法，详见文档《<a href="{{site.url}}{{site.baseurl}}/docs/zh/tutorials/tutorial13_updateloop/">运行时端的更新流程</a>》。</li>
<li>DebugUpdate() ：用于执行调试和热加载相关的方法，如果已经使用了Update()方法来执行，则连调或热加载时就不需要再调用该DebugUpdate()方法。</li>
<li>SetIsExecAgents(bool) ：用于停止/继续执行所有Agent的当前行为树，前提是行为树是执行是通过Update()方法发起的。如果是自己单独调用Agent的btexec()方法，则通过Agent的SetActive(bool)方法来停止/继续执行。</li>
<li>SetTimeSinceStartup(double) ：用于设置游戏从启动到当前的总时间，该总时间主要用于时间、等待时间等与时间有关的节点的执行。如果不每帧设置该值，这些节点将不会正常工作。</li>
<li>SetFrameSinceStartup(int) ：用于设置游戏从启动到当前的总帧数，该总帧数主要用于帧数、等待帧数等与帧数有关的节点的执行。如果不每帧设置该值，这些节点将不会正常工作。</li>
</ul>
<p>具体的代码可以查看<a href="{{site.repository}}/blob/master/inc/behaviac/base/workspace.h">behaviac/base/workspace.h</a></p>
<h3>Agent类</h3>
<p>静态方法：</p>
<ul>
<li>Create(const char*, int, short) ：用于创建Agent的实例。</li>
<li>Destroy(Agent*) ：用于销毁Agent的实例。</li>
<li>Register() ：注册该Agent类，用于记录该类的类型信息。</li>
<li>UnRegister() ：取消注册该Agent类。</li>
<li>RegisterInstanceName(const char*, const wchar_t*, const wchar_t*) ：注册实例名字，作为类型信息的一部分，导出后可用于编辑器中节点的配置。</li>
<li>UnRegisterInstanceName(const char*) ：取消注册实例名字。</li>
<li>BindInstance(Agent*, const char*, int) ：将某个Agent实例跟某个名字进行绑定。</li>
<li>UnbindInstance(const char*, int） ：取消某个Agent实例跟某个名字的绑定。</li>
</ul>
<p>成员方法：</p>
<ul>
<li>btload(const char*, bool) ：用于加载指定名字的行为树，不需要后缀名（文件格式）。</li>
<li>btunload(const char*) ：用于卸载指定名字的行为树。</li>
<li>btsetcurrent(const char*) ：用于设置当前行为树。</li>
<li>btexec() ：执行当前行为树。</li>
<li>SetActive(bool) ：用于停止/继续执行当前行为树，如果设置为false，表示停止执行当前行为树；否则，表示继续执行。</li>
<li>FireEvent(const char*) ：用于发出事件，以便于行为树中绑定的事件得到响应。</li>
<li>SetIdFlag(uint32_t) ：用于设置连调时是否需要跟踪该Agent。通过静态方法SetIdMask()设置全部Agent的Mask值，然后再通过SetIdFlag()设置当前Agent的Flag值。如果IsMasked()返回为真，则表明需要跟踪该Agent。</li>
<li>SetName(const char*) ：用于设置名字。</li>
</ul>
<p>具体的代码可以查看<a href="{{site.repository}}/blob/master/inc/behaviac/agent/agent.h">behaviac/agent/agent.h</a></p>
<h3>Config类</h3>
<p>详见文档《<a href="{{site.url}}{{site.baseurl}}/docs/zh/articles/config/">开发功能开关</a>》。</p>
]]></content:encoded>
					
					<wfw:commentRss>/basic_classes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>使用cmake构建C++版运行时库</title>
		<link>/build/</link>
					<comments>/build/#comments</comments>
		
		<dc:creator><![CDATA[jonygli]]></dc:creator>
		<pubDate>Mon, 11 Apr 2016 09:55:36 +0000</pubDate>
				<category><![CDATA[文章]]></category>
		<category><![CDATA[上手]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[编译构建]]></category>
		<guid isPermaLink="false">/?p=156</guid>

					<description><![CDATA[请首先到/language/zh/downloads/下载或克隆源码。 缺省的，我们使用cmake来生成对应平台的<a class="moretag" href="/build/">Read More...</a>]]></description>
										<content:encoded><![CDATA[<p>请首先到<a href="/language/zh/downloads/#https://github.com/Tencent/behaviac">/language/zh/downloads/</a>下载或克隆源码。</p>
<p id="cpp">缺省的，我们使用<a href="https://cmake.org/download/">cmake</a>来生成对应平台的项目文件（sln或make文件等）。</p>
<p>但cmake不是必须的，也可以选择自己喜欢的方式创建自己的项目文件。比如，使用premake等来生成项目文件，或者手工创建。</p>
<h3></h3>
<h3 id="windows"><span class="ez-toc-section" id="Windows">Windows平台</span></h3>
<ul>
<li>下载并安装<a href="https://cmake.org/download/">cmake</a>，请使用3.3以上版本</li>
<li>cmake的路径需要添加到环境变量PATH</li>
<li>运行build目录下的cmake_generate_projects.bat生成项目文件</li>
<li>如果需要build android版本
<ul>
<li>需要安装vs2015</li>
<li>使用android_vs2015子目录下的项目文件</li>
<li>或者使用cmake生成项目文件
<ul>
<li>下载并安装<a href="https://github.com/Microsoft/CMake/releases">cmake android</a>, 直接覆盖上面步骤安装的cmake就好。</li>
<li>运行build目录下的cmake_generate_projects_android.bat生成项目文件</li>
<li>如果想使用mk，可以修改生成的linux下的make文件</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="section"><span class="ez-toc-section" id="i">其他平台</span></h3>
<ul>
<li>下载并安装<a href="https://cmake.org/">cmake</a>，请使用3.3以上版本</li>
<li>如果可能，请保证4.4.6以上版本的gcc
<ul>
<li>使用版本为4.4.6的gcc可以顺利编译，但4.1.2的gcc有错误（未测试低于4.4.6的版本）</li>
</ul>
</li>
<li>运行build目录下的cmake_generate_projects.sh生成项目文件
<ul>
<li>mac上，运行build目录下的cmake_generate_projects_mac.sh生成项目文件</li>
</ul>
</li>
</ul>
<h3 id="section-1"><span class="ez-toc-section" id="i-2">注意</span></h3>
<ol>
<li>cmake_generate*.bat里使用的是vs2013和vs2015，用户可以根据自己的需要选择相应的编译器，比如vs2008、vs2010等，或者通过cmakegui进行选择。</li>
<li>CMakeLists.txt里提供的是缺省设置，可以根据自己的需要直接修改或通过cmakegui来选择配置。特别的，CMakeLists.txt里有若干个选项可以配置。<br />
<img src="/img/concepts/cmake_config.png" alt="cmake_config" /></p>
<ul>
<li>BEHAVIAC_VERSION_MODE用来控制BEHAVIAC_RELEASE是否定义。BEHAVIAC_RELEASE的用途请参考文章《<a href="/docs/zh/articles/tutorial10_performence">优化及性能</a>》。
<ul>
<li>Default：缺省模式是Debug下BEHAVIAC_RELEASE没有定义，而Release下BEHAVIAC_RELEASE有定义</li>
<li>ForceUseDev：强制不定义BEHAVIAC_RELEASE</li>
<li>ForceUseRelease：强制定义BEHAVIAC_RELEASE
<ul>
<li>在ForceUseRelease的时候，Release下，生成的项目文件会试图打开LTO开关，请参考文档《<a href="/docs/zh/articles/code_size">Cpp生成代码大小的说明</a>》</li>
</ul>
</li>
</ul>
</li>
<li>CMAKE_BUILD_TYPE用来控制生成Debug还是Release（Visual Studio的时候不需要指定CMAKE_BUILD_TYPE）</li>
<li>BUILD_SHARED_LIBS用来控制libbehaviac是stati lib/a还是dynamid dll/so</li>
<li>BUILD_USE_64BITS用来控制是否生成64位 （使用Visual Studio时，需要指定带Win64的generator，请参考cmake的文档）</li>
<li>根据上面的配置，CMake生成下面的_config.h文件，用来自动定义宏BEHAVIAC_RELEASE，如下图所示：<img class="aligncenter size-full wp-image-1650" src="/wp-content/uploads/2016/04/config.png" alt="" width="874" height="286" srcset="/wp-content/uploads/2016/04/config.png 874w, /wp-content/uploads/2016/04/config-300x98.png 300w, /wp-content/uploads/2016/04/config-768x251.png 768w" sizes="(max-width: 874px) 100vw, 874px" /></li>
<li>在另一个文件config.h中，会根据_DEBUG或DEBUG宏来尝试重新定义宏BEHAVIAC_RELEASE，如果在_config.h中宏BEHAVIAC_RELEASE并没有定义，如下图所示：<img class="aligncenter size-full wp-image-1651" src="/wp-content/uploads/2016/04/config-1.png" alt="" width="855" height="372" srcset="/wp-content/uploads/2016/04/config-1.png 855w, /wp-content/uploads/2016/04/config-1-300x131.png 300w, /wp-content/uploads/2016/04/config-1-768x334.png 768w" sizes="(max-width: 855px) 100vw, 855px" /></li>
</ul>
</li>
<li>cmake不是必须的
<ul>
<li>你可以选择自己喜欢的其他类似工具，比如premake等来生成项目文件。</li>
<li>或者，你可以手工创建项目文件。</li>
<li>又或者，可以直接把src和inc加到你已有的项目文件。</li>
<li>当你自行修改或创建项目文件的时候，可能需要参考CMakeLists.txt查看需要的设置：
<ul>
<li>include_directories包含目录，你需要设置正确的包含目录</li>
<li>add_definitions编译宏，比如_DEBUG</li>
<li>add_target_definitions编译宏，比如BEHAVIACDLL_EXPORTS，BEHAVIAC_DLL</li>
<li>CMAKE_CXX_FLAGS编译开关</li>
<li>BUILD_SHARED_LIBS是否动态库还是静态库</li>
</ul>
</li>
</ul>
</li>
<li>build\android_vs2015是提供的缺省的使用Visual Studio 2015来生成android项目的项目工程，支持64位。</li>
<li>可以使用cmakegui选择设置，或者在cmake的命令行里指定设置（ -DCMAKE_BUILD_TYPE=Debug -DBUILD_USE_64BITS=ON等）。请参考<a href="https://github.com/Tencent/behaviac/blob/master/build/cmake_generate_projects.bat">build/cmake_generate_projects.bat</a>或者cmake文档。</li>
</ol>
<h3 id="section-2"><span class="ez-toc-section" id="i-3">构建</span></h3>
<ul>
<li>无论Windows平台还是其他平台，项目文件都生成到目录cmake_binary</li>
<li>项目文件生成到目录cmake_binary，根据选用的编译工具（vs2013、make等）打开相应目录的项目文件或运行make等进行构建</li>
<li>.a、.lib、.dll、.exe等被生成到根目录的lib目录和bin目录</li>
<li>生成的项目配置(mvsc, linxu, xcode)包含了Debug和Release，请根据需要构建Debug或Release版本</li>
</ul>
<h2 id="unity"></h2>
]]></content:encoded>
					
					<wfw:commentRss>/build/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
	</channel>
</rss>
