﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-点点滴滴-随笔分类-19 源码收集</title><link>http://www.cppblog.com/ming81/category/15290.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 18 Dec 2016 21:13:20 GMT</lastBuildDate><pubDate>Sun, 18 Dec 2016 21:13:20 GMT</pubDate><ttl>60</ttl><item><title>(搬运工)Mangos代码阅读  </title><link>http://www.cppblog.com/ming81/archive/2016/12/16/214503.html</link><dc:creator>点点滴滴</dc:creator><author>点点滴滴</author><pubDate>Fri, 16 Dec 2016 03:28:00 GMT</pubDate><guid>http://www.cppblog.com/ming81/archive/2016/12/16/214503.html</guid><description><![CDATA[<h3><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #626a0f; font-family: &quot;Hiragino Sans GB W3&quot;, &quot;Hiragino Sans GB&quot;, Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; font-weight: normal; background-color: #f4f0e8;">逻辑层： 类World实现了wow的World，所有的逻辑处理<br style="line-height: 28px;" />　　MaNGOS 下载，编译，配置和运行的基本步骤 下载和安装msysgit，用于代码管理我使用的是Git-1.6.5.1-preview20091022.exe&nbsp;<br style="line-height: 28px;" />　　下载和安装tortoisegit，用于代码管理我使用的是TortoiseGit-1.3.2.0-32bit.msi&nbsp;<br style="line-height: 28px;" />　　使用git://github.com/mangos/mangos.git，从github提取mangos代码&nbsp;<br style="line-height: 28px;" />　　采用Git GUI工具的Clone Existing Repository，得到 mangos代码（我的是9560，安装UDB参考这）&nbsp;<br style="line-height: 28px;" />　　使用git://github.com/scriptdev2/scriptdev2.git，从github提取scriptdev2代码&nbsp;<br style="line-height: 28px;" />　　采用Git GUI工具的Clone Existing Repository，得到 scriptdev2代码.&nbsp;<br style="line-height: 28px;" />　　编译mangos我用的是VC9,打开mangoswinmangosdVC90.sln进行构造，构造完成后，会得到mangosbinWin32_Debug文件夹&nbsp;<br style="line-height: 28px;" />　　编译scriptdev2我用的是VC9,打开mangoswinscriptdev2VC90.sln进行构造，构造完成后，会得到scriptdev2binWin32_Debug文件夹也可参考&nbsp;<br style="line-height: 28px;" />　　pandore&nbsp;<br style="line-height: 28px;" />　　拷贝mangossrcmangosd目录下的mangosd.conf.dist.in为mangosbinWin32_Debugmangosd.conf&nbsp;<br style="line-height: 28px;" />　　拷贝mangossrcrealmd目录下的realmd.conf.dist.in为mangosbinWin32_Debugrealmd.conf&nbsp;<br style="line-height: 28px;" />　　从http://www.wowtaiwan.com.tw/下载和安装台服WOW，并升级到最新版本我使用的是台服WOW 3.3.2 build 11403&nbsp;<br style="line-height: 28px;" />　　，采用MaNGOS的工具ad从wow的MPQ中抽取map，得到的所有的map数据文件，文件命名规范为map_id（3位） tileY（2位） tileX（2位）.map，如文件名为0002035.map，代表的是Azeroth(地图id为000，tile坐标为(35,20). 注：WOW客户端的Tile对应mangos中的grid，WOW客户端的Chunk对应mangos中的cell(1cell = 4 chunk)&nbsp;<br style="line-height: 28px;" />　　按照常规流程（包括建立数据库和配置服务器）把服务器跑起来，使用account create zzh1234567 zzh1234567 创建一个账号，使用account set gmlevel zzh1234567 3设置为超级用户&nbsp;<br style="line-height: 28px;" />　　配置好客户端后，运行WOW，顺利登陆，呵呵&nbsp;<br style="line-height: 28px;" />　　通过安装UDB来丰富场景FULL DB 9560 : HERE，参考这，在我安装DB9560的时候，发现Mangos在LoadCreatureAddons的时候，加载creature template addons出错，Mangos只要求creature template addons有7个字段，而creature template addons有9个字段我现在只是简单地跳过LoadCreatureAddons的调用&nbsp;<br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="http://img.blog.163.com/photo/nk6LytF-0DMhcR5vrhJpRA==/5745748699595153200.jpg" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" />&nbsp;<br style="line-height: 28px;" />运行Mangos （运行Mangos一节过期，是以前我针对国服3.1.3版本进行的安装配置） ，采用MaNGOS的工具ad从wow的MPQ中抽取map，得到的所有的map数据文件，文件命名规范为map_id（3位） tileY（2位） tileX（2位）.map，如文件名为0002035.map，代表的是Azeroth(地图id为000，tile坐标为(35,20). 注：WOW客户端的Tile对应mangos中的grid，WOW客户端的Chunk对应mangos中的cell(1cell = 4 chunk)&nbsp;<br style="line-height: 28px;" />　　配置好客户端后，运行WOW，顺利登陆，呵呵&nbsp;<br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="https://wsfuhw.bay.livefilestore.com/y1mCPMAf5KpqxNxMiGTm_jTIFqbdQU6VJiInnLGoYBJwzSh15UeaTMg6uOvbFJtgfNNySLdazNb0yjXzeFqI36EFxEIhP5Xb2yK7V72Y3FZ9EH8TZ7YIExZSkB4HhtQQ7ENavODPjS5BjPIKZetdbNLqA/image_thumb[1]%20721A1A07.png" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" />&nbsp;<br style="line-height: 28px;" />Mangos代码阅读&nbsp;<br style="line-height: 28px;" />　　Mangos有13个工程&nbsp;<br style="line-height: 28px;" />　　使用了4个外部工具库，分别是： 跨平台的网络通讯框架The ADAPTIVE Communication Environment (ACE)&nbsp;<br style="line-height: 28px;" />　　压缩库zlib&nbsp;<br style="line-height: 28px;" />　　Socket通信库 C++ Sockets Library (使用在realmd工程中，和使用在Mangosd工程中的RASocket，负责处理Remote Administration其他地方没有使用到这个C++ Sockets Library ）发现在C++ Sockets Library的TcpSocket::Open中存在一个问题，在n = connect(s, ad, ad);语句执行后，如果n=-1，C++ Sockets Library会检测是否ERR为WSAEWOULDBLOCK，否则表示成功，但在动态库中使用TcpSocket的时候，我发现n = connect(s, ad, ad);语句执行后，n=-1，ERR会为0，这个时候连接也是成功了，但TcpSocket::Open会当做不成功处理我发现这个问题，但没有时间去探究原因，也许并不是一个问题&nbsp;<br style="line-height: 28px;" />　　C++的并行编程模板库Threading Building Blocks （tbb 和 tbbmalloc）&nbsp;<br style="line-height: 28px;" />　　Mangos的实现分为：登录服务器（realmd）和世界服务器（mangosd+game）realmd和mangos共用了Mangos公共库（shared）&nbsp;<br style="line-height: 28px;" />　　工程shared&nbsp;<br style="line-height: 28px;" />　　提供了通用功能，包括了数据库的封装类，实现了对MySql的访问，同样，我们可以编写派生类来支持其他的数据库&nbsp;<br style="line-height: 28px;" />　　工程script&nbsp;<br style="line-height: 28px;" />　　提供了脚本接口，并实现了简单的几个脚本，封装为DLL，提供给game使用，具体可参考：MaNGOS脚本接口&nbsp;<br style="line-height: 28px;" />　　通过使用不同的脚本DLL来替换share的这个DLL,可以让game具有更强的AIScriptDev2 就是一个这样的库ScriptDev2 is a replacement for the Script Library that comes with MaNGOS( http://www.getmangos.com ) written in C++ and is compatible with Windows and Linux. It provides scripts for NPCs, Boss events, and Items currently. On<wbr style="line-height: 28px;">ce ScriptDev2 is compiled it is automatically run by MaNGOS on server startup.&nbsp;<br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="https://wsfuhw.bay.livefilestore.com/y1mqFJsXeSbhabwV6AbfzaxEFJu7HHpFQ19ZZ2xgmMiGNpK61hWRoXnQaUiP173L2bea7a6xYc0c4iqbEVe43wz2vW0U5UesrKiAuDvpZ-FjKQDf41SxlZ_VGFVE12JuMEzo0YMjb6D9NhDa3fDwh0qNQ/image_thumb[3]%20126B330F.png" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" /></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #626a0f; font-family: &quot;Hiragino Sans GB W3&quot;, &quot;Hiragino Sans GB&quot;, Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; font-weight: normal; background-color: #f4f0e8;">工程mangosd&nbsp;<br style="line-height: 28px;" />　　mangos是世界服务器的管理器，负责初始化工作和启动世界服务器各层的线程，这些工作主要是由类Master来实现具体是： 使用三个数据库对象WorldDatabase和CharacterDatabase和loginDatabase，初始化三大数据库：World Database和Character Database和login Database，并为每个数据库的访问都启动一个DB delay threads具体的数据库操作功能都是由Mangos公共库shared来提供&nbsp;<br style="line-height: 28px;" />　　调用sWorld.SetInitialWorldSettings，对World进行初始化，包括加载所有的游戏数据和初始化各种更新定时器和邮件定时器，还有些其他的初始化工作类World的成员函数SetInitialWorldSettings调用成员函数LoadConfigSettings解析mangosd.conf，解析后内容放入uint32 m_configs[CONFIG_VALUE_COUNT]中&nbsp;<br style="line-height: 28px;" />　　加载的游戏数据有：&nbsp;<br style="line-height: 28px;" />　　DBC数据&nbsp;<br style="line-height: 28px;" />　　Objects数据&nbsp;<br style="line-height: 28px;" />　　Spells数据&nbsp;<br style="line-height: 28px;" />　　Pooling数据&nbsp;<br style="line-height: 28px;" />　　Game Event数据&nbsp;<br style="line-height: 28px;" />　　loot数据&nbsp;<br style="line-height: 28px;" />　　技能数据&nbsp;<br style="line-height: 28px;" />　　所有其他的游戏数据，包括Waypoints和Trainers等等等&nbsp;<br style="line-height: 28px;" />　　脚本数据&nbsp;<br style="line-height: 28px;" />　　其他的初始化工作有:&nbsp;<br style="line-height: 28px;" />　　初始化MapManager，启动Map System&nbsp;<br style="line-height: 28px;" />　　初始化Battlegrounds，启动BattleGround System&nbsp;<br style="line-height: 28px;" />　　初始化DailyQuestResetTime&nbsp;<br style="line-height: 28px;" />　　初始化sGameEventMgr，Starting Game Event system&nbsp;<br style="line-height: 28px;" />　　类Master启动WorldRunnable，开始游戏逻辑Heartbeat for the World，由Master创建，并设置线程为最高优先级&nbsp;<br style="line-height: 28px;" />　　类Master启动CliRunnable：Command Line Interface handling thread，由Master创建CliRunnable运行时候会生成一个WorldDatabase线程，在接收到输入后会调用sWorld.QueueCliCommand把Cmd放入到World::cliCmdQueue中&nbsp;<br style="line-height: 28px;" />　　mangosd的线程总共有（1+3+1+1+1+2 +1 =10）10个线程 主线程Master&nbsp;<br style="line-height: 28px;" />　　2个网络线程ReactorRunnable（可配置数目）（网络层）&nbsp;<br style="line-height: 28px;" />　　一个World线程（逻辑层）&nbsp;<br style="line-height: 28px;" />　　三个DB线程（数据层）&nbsp;<br style="line-height: 28px;" />　　一个CLI线程（输入层），运行时候会生成一个WorldDatabase线程&nbsp;<br style="line-height: 28px;" />　　一个RA线程（管理层）&nbsp;<br style="line-height: 28px;" />　　一个freeze catcher 线程（可选）&nbsp;<br style="line-height: 28px;" />　　工程g3dlite：游戏逻辑层的底层库&nbsp;<br style="line-height: 28px;" />　　工程framework：系统框架&nbsp;<br style="line-height: 28px;" />　　工程realm&nbsp;<br style="line-height: 28px;" />　　负责登陆和选择游戏服务器，进行负载均衡用到了C++ Sockets Library进行登录处理，采用select I/O模型实现了Wow, Mangos登录时的SRP6认证客户端作为它的client连接到realm server认证和选择了mangos server就断开 而mangos server和realm server则不进行连接，只是通过数据库交互数据：mangos server把自己的状态和拥有的角色数放入库中realm server会读取数据库中的这些信息来获知mangos server的状态 数据库realm的realmlist表保存了realm的列表&nbsp;<br style="line-height: 28px;" />　　realm通过如下事件处理函数来负责登陆和选择游戏服务器&nbsp;<br style="line-height: 28px;" />　　const AuthHandler table[] =&nbsp;<br style="line-height: 28px;" />　　{&nbsp;<br style="line-height: 28px;" />　　{ AUTH_LOGON_CHALLENGE, STATUS_CONNECTED, &amp;AuthSocket::_HandleLogonChallenge },&nbsp;<br style="line-height: 28px;" />　　{ AUTH_LOGON_PROOF, STATUS_CONNECTED, &amp;AuthSocket::_HandleLogonProof },&nbsp;<br style="line-height: 28px;" />　　{ AUTH_RECONNECT_CHALLENGE, STATUS_CONNECTED, &amp;AuthSocket::_HandleReconnectChallenge},&nbsp;<br style="line-height: 28px;" />　　{ AUTH_RECONNECT_PROOF, STATUS_CONNECTED, &amp;AuthSocket::_HandleReconnectProof },&nbsp;<br style="line-height: 28px;" />　　{ REALM_LIST, STATUS_AUTHED, &amp;AuthSocket::_HandleRealmList },&nbsp;<br style="line-height: 28px;" />　　{ XFER_ACCEPT, STATUS_CONNECTED, &amp;AuthSocket::_HandleXferAccept },&nbsp;<br style="line-height: 28px;" />　　{ XFER_RESUME, STATUS_CONNECTED, &amp;AuthSocket::_HandleXferResume },&nbsp;<br style="line-height: 28px;" />　　{ XFER_CANCEL, STATUS_CONNECTED, &amp;AuthSocket::_HandleXferCancel }&nbsp;<br style="line-height: 28px;" />　　}; 登录处理：&nbsp;<br style="line-height: 28px;" />　　user登录到realm server进行身份认证，并选择登录上哪个mangos serveruser登录到mangos server后，将不再和realm server交互&nbsp;<br style="line-height: 28px;" />　　参考： Wow 服务器解析&nbsp;<br style="line-height: 28px;" />　　工程game&nbsp;<br style="line-height: 28px;" />　　game：是Mangos的核心代码，网络层和逻辑层代码(采用了ACE反应器(Reactor)模式）&nbsp;<br style="line-height: 28px;" />　　网络层： WorldSocket ：负责网络IO,而类WorldSession负责逻辑处理WorldSocket和WorldSession分别在独立的线程ReactorRunnable和WorldRunnable中运行，使用WorldSession中的消息队列_recvQueue来进行数据缓冲在WorldSocket接收到网咯输入后，会调用m_Session-&gt;QueuePacket (new_pct);把网络包放入WorldSession的_recvQueue所以，可以看到WorldSocket 是Mangos game的网络层，而WorldSession是逻辑处理层WorldSocketMgr是网络层的一个管理器，它负责指派WorldSocket归哪个ReactorRunnable管理（Mangos可创建多个ReactorRunnable，缺省是2个）&nbsp;<br style="line-height: 28px;" />　　WorldSocketMgr（Manages all sockets connected to peers and network threads）管理所有的连接WorldSocketWorldSocketMgr的WorldSocketMgr::StartNetwork对8085（缺省）端口进行侦听逻辑处理的循环是在World::Update中循环处理包括：&nbsp;<br style="line-height: 28px;" />　　刷新更新定时器&nbsp;<br style="line-height: 28px;" />　　刷新游戏定时器和处理游戏关闭&nbsp;<br style="line-height: 28px;" />　　处理日常任务&nbsp;<br style="line-height: 28px;" />　　处理拍卖&nbsp;<br style="line-height: 28px;" />　　刷新SessionsWorld::UpdateSessions会调用所有WorldSession的WorldSession::Update在WorldSession::Update中进行逻辑处理&nbsp;<br style="line-height: 28px;" />　　处理天气&nbsp;<br style="line-height: 28px;" />　　刷新uptime table&nbsp;<br style="line-height: 28px;" />　　刷新Objects，包括maps，transport，creatures，，，，&nbsp;<br style="line-height: 28px;" />　　刷新所有running battlegrounds&nbsp;<br style="line-height: 28px;" />　　刷新SqlResultQueue, 逻辑层和数据层是通过Queue来进行异步操作的（用了AsyncPQuery和SqlResultQueue）&nbsp;<br style="line-height: 28px;" />　　处理尸体移除&nbsp;<br style="line-height: 28px;" />　　处理游戏事件&nbsp;<br style="line-height: 28px;" />　　处理 Move all creatures with "delayed move" and remove and delete all objects with "delayed remove"&nbsp;<br style="line-height: 28px;" />　　处理InstanceSaveManager的刷新&nbsp;<br style="line-height: 28px;" />　　调用World::ProcessCliCommands，处理CLI从cliCmdQueue取得cmd进行解析执行所有有效的Cmd，都可以在ChatHandler::getCommandTable中找到&nbsp;<br style="line-height: 28px;" />　　类WorldSession： 类WorldSession负责逻辑处理&nbsp;<br style="line-height: 28px;" />　　void WorldSession::SendPacket(WorldPacket const* packet) 负责发包给客户端，直接发包，没有输出缓冲队列&nbsp;<br style="line-height: 28px;" />　　在WorldSession::Update中进行逻辑处理World::UpdateSessions会调用所有WorldSession的WorldSession::Update&nbsp;<br style="line-height: 28px;" />　　执行语句OpcodeHandler&amp; opHandle = opcodeTable[packet-&gt;GetOpcode()];得到opHandle&nbsp;<br style="line-height: 28px;" />　　根据得到的opHandle，执行(this-&gt;*opHandle.handler)(*packet);&nbsp;<br style="line-height: 28px;" />　　WorldSession::HandlePlayerLogin处理玩家登陆游戏&nbsp;<br style="line-height: 28px;" />　　构建Player&nbsp;<br style="line-height: 28px;" />　　Player::LoadFromDB从数据库中加载玩家数据在Player::LoadFromDB中会调用SetMap(MapManager::Instance().CreateMap(GetMapId() , this));加载当前player所在的map&nbsp;<br style="line-height: 28px;" />　　Player::SetPosition在Player运动的时候，改变位置，保存处理夸区&nbsp;<br style="line-height: 28px;" />　　类Map实现了一个state machine，采用state pattern组织了Gid的4个state object：InvalidState；ActiveState；IdleState；RemovalState&nbsp;<br style="line-height: 28px;" />　　game中的管理器有： ObjectMgr&nbsp;<br style="line-height: 28px;" />　　mMangosStringLocaleMap 关联到mangos_string table&nbsp;<br style="line-height: 28px;" />　　m_scriptNames 关联到tables: creature_template;gameobject_template;item_templat e;areatrigger_scripts;instance_template&nbsp;<br style="line-height: 28px;" />　　mCreatureLocaleMap 关联到locales_creature table&nbsp;<br style="line-height: 28px;" />　　mGameObjectLocaleMap关联到locales_gameobject table&nbsp;<br style="line-height: 28px;" />　　mItemLocaleMap关联到locales_item table&nbsp;<br style="line-height: 28px;" />　　mQuestLocaleMap &#8211;&gt; locales_quest&nbsp;<br style="line-height: 28px;" />　　mNpcTextLocaleMap &#8211;&gt; locales_npc_text&nbsp;<br style="line-height: 28px;" />　　mPageTextLocaleMap &#8211;&gt; locales_page_text&nbsp;<br style="line-height: 28px;" />　　mGossipMenuItemsLocaleMap &#8211;&gt; locales_gossip_menu_option&nbsp;<br style="line-height: 28px;" />　　mPointOfInterestLocaleMap &#8211;&gt; locales_points_of_interest&nbsp;<br style="line-height: 28px;" />　　&#8230;&nbsp;<br style="line-height: 28px;" />　　对象类层次&nbsp;<br style="line-height: 28px;" />　　对象的类层次如下，所有的Object都由ObjectMgr进行管理ObjectMgr以GUID方式，管理了characters，creature，item_instance，gameobject，auctionhouse，mail，item_text，corpse，arena_team，character_equipmentsets&nbsp;<br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="https://wsfuhw.bay.livefilestore.com/y1mezwfVaPkXmsk3Zf0dwoWJ020hyAh8kevkkTl4VfX5tnOAdYTxDAlJuV0KmEoZDZEBONFJYghah-QT4vJ6OHcrSg99KVIgOdb8F-ZIh3DsFzSZ0ygQgHF5OmRxOhGMVLJdWPFl-sDmEhwm65Gz0tGfw/image_thumb[6]%20234AFB02.png" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" /><br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="https://wsfuhw.bay.livefilestore.com/y1mSeFQhf-cu8JF3AlYR6g9awDvodhsMZVstPelOgPh2nOMnzTAh4khjKA4ibev67tXMU-WqT9-xqk_o4fFCfVzrf4xUtmOHqZ1zHItsmwkh_9-2BvG1R3DaYO5XqXtZR2Iej59VVViMM2XPb_H6qK-HQ/image_thumb[1]%207E489568.png" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" /><br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="https://wsfuhw.bay.livefilestore.com/y1mT7RvHwVNpBBwOaDN-466VGTqeP8s0H1YaELXlBcjfi4XCherjjQ0H_jOzBT1VyueDvrQ9A62ulG4CilIG8qQ-p7L05PaMCFvnNC1lv0pzMOu_t8Qf6d4Hu7Lhys7JXSAzdlDOkkszBsdxxdfyNFgOg/image_thumb[22].png" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" /><br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="https://wsfuhw.bay.livefilestore.com/y1meJP6Trbl4-a6Rpw8NiMuAwE4O1rsOjmMUcSk4Sz830moO3T95P4zAuv8M0Evc6fVL6gVriveYGwEbs0d9LdzkV_ig2bexhLgIiAwseKtXcUdvVeQm0FxXRlR6SqOWDfE1k-dnLzcZIM4js3f59CaCg/image_thumb[40].png" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" /><br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="https://wsfuhw.bay.livefilestore.com/y1mxW4XULPDcsbliWGSeGjUu_HKZ67xO-_FaNyK5MITYmkFiDHA-GdeoVJ0fWHWajB2W0CffOOs0SsYDTdDznqfmdIUrIEFkce4Qh0ktTaEl1AAQrP5ncaLpE67pqUwm3-hj5jUkOHmNG0XujQ63AuSWQ/image_thumb[30].png" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" /></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #626a0f; font-family: &quot;Hiragino Sans GB W3&quot;, &quot;Hiragino Sans GB&quot;, Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; font-weight: normal; background-color: #f4f0e8;">Player状态&nbsp;<br style="line-height: 28px;" />　　/// Player state&nbsp;<br style="line-height: 28px;" />　　enum SessionStatus&nbsp;<br style="line-height: 28px;" />　　{&nbsp;<br style="line-height: 28px;" />　　STATUS_AUTHED = 0, ///&lt; Player authenticated (_player==NULL, m_playerRecentlyLogout = false or will be reset before handler call, m_GUID have garbage)&nbsp;<br style="line-height: 28px;" />　　STATUS_LOGGEDIN, ///&lt; Player in game (_player!=NULL, m_GUID == _player-&gt;GetGUID(), inWorld())&nbsp;<br style="line-height: 28px;" />　　STATUS_TRANSFER, ///&lt; Player transferring to another map (_player!=NULL, m_GUID == _player-&gt;GetGUID(), !inWorld())&nbsp;<br style="line-height: 28px;" />　　STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, ///&lt; _player!= NULL or _player==NULL &amp;&amp; m_playerRecentlyLogout, m_GUID store last _player guid)&nbsp;<br style="line-height: 28px;" />　　STATUS_NEVER ///&lt; Opcode not accepted from client (deprecated or server side on<wbr style="line-height: 28px;">ly)&nbsp;<br style="line-height: 28px;" />　　};&nbsp;<br style="line-height: 28px;" />　　生物状态&nbsp;<br style="line-height: 28px;" />　　enum DeathState&nbsp;<br style="line-height: 28px;" />　　{&nbsp;<br style="line-height: 28px;" />　　ALIVE = 0,&nbsp;<br style="line-height: 28px;" />　　JUST_DIED = 1,&nbsp;<br style="line-height: 28px;" />　　CORPSE = 2,&nbsp;<br style="line-height: 28px;" />　　DEAD = 3,&nbsp;<br style="line-height: 28px;" />　　JUST_ALIVED = 4,&nbsp;<br style="line-height: 28px;" />　　DEAD_FALLING= 5&nbsp;<br style="line-height: 28px;" />　　};&nbsp;<br style="line-height: 28px;" />　　玩家登陆&nbsp;<br style="line-height: 28px;" />　　服务器端在连接打开后，会发SMSG_AUTH_CHALLENGE到客户端客户端从服务器端发送回来的种子和 SRP6 数据中产生随机种子，生成 SHA1 字符串，用这些数据生成 CMSG_AUITH_SESSION 数据包，发送给服务端这个过程是没有经过加密的&nbsp;<br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="https://wsfuhw.bay.livefilestore.com/y1myrugHT4h_SUMCTDKu69LYqlZoo1C6QGJvXxzxHHZLJ9MfA53trcyNEH4Mmuykyg7HJuP8zgb89yuew0_bpQhxce-meEZ9tu30YZctW5kMjUXqCAB581CtOc4XzIxOd-X-vvlO3-pWW77rNMZofk6gw/image_thumb[5]%2070AFBBEE.png" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" /><br style="line-height: 28px;" />　　客户端发送SMSG_AUTH_SESSION到服务器&nbsp;<br style="line-height: 28px;" />　　服务器处理SMSG_AUTH_SESSION&nbsp;<br style="line-height: 28px;" />　　服务器发送SMSG_AUTH_RESPONSE给客户端&nbsp;<br style="line-height: 28px;" />　　服务器发送SMSG_ADDON_INFO给客户端&nbsp;<br style="line-height: 28px;" />　　服务器发送SMSG_CLIENTCACHE_VERSION给客户端&nbsp;<br style="line-height: 28px;" />　　服务器发送SMSG_TUTORIAL_FLAGS给客户端&nbsp;<br style="line-height: 28px;" />　　packet结构 SMSG_AUTH_SESSION 是client packet有一个头部（ClientPktHeader），后面是数据块&nbsp;<br style="line-height: 28px;" />　　SMSG_AUTH_RESPONSE 是server packet有一个头部（ServicePktHeader），后面是数据块&nbsp;<br style="line-height: 28px;" />　　SMSG_AUTH_RESPONSE 的包组织&nbsp;<br style="line-height: 28px;" />　　SMSG_AUTH_RESPONSE 的opcode是01EE，ByteBuffer大小为1 + 4 + 1 + 4 + 1=11一个SMSG_AUTH_RESPONSE 的数据如下： 在构造了SMSG_AUTH_RESPONSE packet后，WorldSocket::SendPacket会根据SMSG_AUTH_RESPONSE packet构造出一个ServerPktHeader，并对ServerPktHeader中的数据header进行加密发送加密采用m_Crypt.EncryptSend ((uint8*)header.header, header.getHeaderLength()); WorldSocket::handle_input_header会对从客户端接收来的数据进行解密，解密采用m_Crypt.DecryptRecv ((uint8*) m_Header.rd_ptr (), sizeof (ClientPktHeader));&nbsp;<br style="line-height: 28px;" />　　角色枚举 玩家登上服务器后，从客户端发送SMSG_CHAR_ENUM到服务器&nbsp;<br style="line-height: 28px;" />　　在服务器端&nbsp;<br style="line-height: 28px;" />　　根据{ "CMSG_CHAR_ENUM", STATUS_AUTHED, &amp;WorldSession::HandleCharEnumOpcode }，服务器会调用WorldSession::HandleCharEnumOpcode&nbsp;<br style="line-height: 28px;" />　　WorldSession::HandleCharEnumOpcode会调用CharacterDatabase.AsyncPQuery，进行异步查询后，调用CharacterHandler::HandleCharEnumCallback&nbsp;<br style="line-height: 28px;" />　　CharacterHandler::HandleCharEnumCallback会回头调用session-&gt;HandleCharEnum(result);&nbsp;<br style="line-height: 28px;" />　　WorldSession::HandleCharEnum根据characters数据库的查询结果，调用Player::BuildEnumData，加载角色数据，构造SMSG_CHAR_ENUM返回包，然后发送回客户端&nbsp;<br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="https://wsfuhw.bay.livefilestore.com/y1m8ZD9-XlfQA8Q1yJ1agajqbkHnaHqNU1VbHxCsPTFDfIJ4OC_JmYeQIFdTYaemThsxhVC_G_OQUNlDrVs-dnH85azLY8Thfwp3fMh0PzRBW59jjqC_xy997lQZKJVhhOHSUJ_Vavj2TDVQixvnQIULw/image_thumb[7]%2019A3906E.png" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" /><br style="line-height: 28px;" />　　角色创建&nbsp;<br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="https://wsfuhw.bay.livefilestore.com/y1mL0KCHJ1KyP-57ZRdq6litvfO5PHE6zTz6X8W_ftPW_nv-nVsVmxGycNDfNYxUc15j95fsxE79DM9AIzY8RTlZa8JdjeCQk2Ol9_JzA-7i8o6TSFEkOMU4VAIBGHJi7MmlPpYrUWKCMP-aqBZeevuUw/image_thumb[11].png" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" />&nbsp;<br style="line-height: 28px;" />　　角色的初始化装备在CharStartOutfit.dbc&nbsp;<br style="line-height: 28px;" />　　角色的创建和选择的设置都在 ChrRaces.dbc&nbsp;<br style="line-height: 28px;" />　　角色的创建属性都在Playercreateinfo，包括出生地和出生属性&nbsp;<br style="line-height: 28px;" />　　playercreateinfo_item表是创建一个新人物时，人物默认带的所有Item的表&nbsp;<br style="line-height: 28px;" />　　playercreateinfo_spell表是创建一个新人物时，人物默认带的所有Spell的表&nbsp;<br style="line-height: 28px;" />角色删除&nbsp;<br style="line-height: 28px;" />　　<img alt="Mangos代码阅读 - 陈波 - cp7618@yeah的博客" src="https://wsfuhw.bay.livefilestore.com/y1mywq82hNegSdJMMB43uxMcB6ixhoh6XSHoXsU1_lB_XKxzPC3V2bfAQQJRNVI129y5GXrZyUqQMEkk1WonG3n4wxPPPzfZsFfwA9GEazHwFXcXuA23ImQ4R3Xx58eXpe2bIbu1NxzlVDgO2AXJhCmuQ/image_thumb[13].png" style="line-height: 28px; border: 0px; max-width: 100%; height: auto;" /></p></h3><img src ="http://www.cppblog.com/ming81/aggbug/214503.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ming81/" target="_blank">点点滴滴</a> 2016-12-16 11:28 <a href="http://www.cppblog.com/ming81/archive/2016/12/16/214503.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(搬用工)mangos新手教程 - 服务器配置文件中文说明</title><link>http://www.cppblog.com/ming81/archive/2016/12/16/214497.html</link><dc:creator>点点滴滴</dc:creator><author>点点滴滴</author><pubDate>Fri, 16 Dec 2016 03:16:00 GMT</pubDate><guid>http://www.cppblog.com/ming81/archive/2016/12/16/214497.html</guid><description><![CDATA[<div style="box-sizing: border-box; word-break: break-all; color: #333333; font-family: sans-serif; font-size: 24px; background-color: #ffffff;"></div><table border="0" style="box-sizing: border-box; border-collapse: collapse; border-spacing: 0px; max-width: 100%; background-color: #ffffff; word-break: break-all; border-width: 0.05rem; border-style: solid; border-color: #eeeeee; color: #333333; font-family: sans-serif; font-size: 24px; table-layout: fixed;"><tbody style="box-sizing: border-box;"><tr style="box-sizing: border-box;"><td style="box-sizing: border-box; border-width: 0.05rem; border-style: solid; border-color: #eeeeee;"><div id="blog_text" style="box-sizing: border-box; word-break: break-all;"><div style="box-sizing: border-box; word-break: break-all;"># MaNGOS Configuration file 服务器配置文件中文说明<br style="box-sizing: border-box;" />ConfVersion=2007071001<br style="box-sizing: border-box;" /># RealmID must match the realmlist (国度ID 必牒凸 攘斜砝锩娴南喾?<br style="box-sizing: border-box;" />RealmID = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 0 NORMAL 1 PVP 4 NORMAL 6 RP 8 RPPVP(服务器类型)<br style="box-sizing: border-box;" />GameType = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 扩展柚每 ?# 0 不检查扩展地图,不允许创建新种族,忽略账号的扩展设置.<br style="box-sizing: border-box;" /># 默认: 1 (如果客户端支持扩展且账号拥有扩展权限,即允许使用新种族及访问新地图.)<br style="box-sizing: border-box;" />Expansion = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#==================================服务端添加的参数===========================================================================<br style="box-sizing: border-box;" />#世界聊天消费(默认是1G/次)<br style="box-sizing: border-box;" />sjxf=10000<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#初始人物金币，以分为单位.<br style="box-sizing: border-box;" /># 默认: 8<br style="box-sizing: border-box;" />mymoney = 1000000<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 自动公告时间间隔 1=1秒<br style="box-sizing: border-box;" />AutoBroadcastInterval=10&nbsp;<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#初始怪物尸体停留时间<br style="box-sizing: border-box;" />#单位/秒&nbsp;<br style="box-sizing: border-box;" /># 默认: 60<br style="box-sizing: border-box;" />MyCropseDelay = 60<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#人物复活虚弱时间<br style="box-sizing: border-box;" />#默认: 1000<br style="box-sizing: border-box;" />Playerdietime = 1000<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#初始出生人物等级<br style="box-sizing: border-box;" /># 默认: 1<br style="box-sizing: border-box;" />LevelFirst = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#加血技能治疗倍数<br style="box-sizing: border-box;" />aurahealing = 5<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#法术技能伤害倍数<br style="box-sizing: border-box;" />tmpDamage = 5<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#物理技能伤害倍数(数字别改的太大了)<br style="box-sizing: border-box;" />pdaDamage = 2<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#猎人闪避率设置(数字越大闪避率越低)<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />Rate.Hunter_Max.Dodge=31.4<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#盗贼闪避率设置(数字越大闪避率越低)<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />Rate.Roguer_Max.Dodge=19.5<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#其他职业闪避率设置(数字越大闪避率越低)<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />Rate.Else_Max.Dodge=27<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#==================================服务端添加的参数===========================================================================<br style="box-sizing: border-box;" /># 数据目录设置。<br style="box-sizing: border-box;" /># 重要说明：数据目录需要放在引号里面，因为字符串可能包含空格<br style="box-sizing: border-box;" /># DataDir = "@MANGOSD_DATA@" //这个是默认目录<br style="box-sizing: border-box;" />DataDir = "./"<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># Logs directory setting.<br style="box-sizing: border-box;" /># Important: Logs dir must exists, or all logs be disable<br style="box-sizing: border-box;" /># Default: "" - no log directory prefix, if used log names isn't absolute path then logs will be stored in current directory for run program.<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />LogsDir = ""<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 世界服务器的数据库连接设置。<br style="box-sizing: border-box;" /># 格式：主机地址(域名或IP）;端口;用户名;密码;数据库名称<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .;somenumber;username;password;database - use named pipes at Windows<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Named pipes: mySQL required adding "enable-named-pipe" to [mysqld] section my.ini<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .;/path/to/unix_socket;username;password;database - use Unix sockets at Unix/Linux<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Unix sockets: experimental, not tested<br style="box-sizing: border-box;" />LoginDatabaseInfo = "127.0.0.1;3306;root;netspace;realmd"<br style="box-sizing: border-box;" />WorldDatabaseInfo = "127.0.0.1;3306;root;netspace;mangos"<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 设置最高ping数据库的时间间隔(分钟)<br style="box-sizing: border-box;" />MaxPingTime = 30<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># DBC 语言设置<br style="box-sizing: border-box;" />#8 英语<br style="box-sizing: border-box;" />#4 韩语<br style="box-sizing: border-box;" />#3 法语<br style="box-sizing: border-box;" />#3 德语<br style="box-sizing: border-box;" />#4 中文<br style="box-sizing: border-box;" />#5 台湾繁体<br style="box-sizing: border-box;" />#6 西班牙语<br style="box-sizing: border-box;" />#7 俄语<br style="box-sizing: border-box;" />#8 未知&nbsp;<br style="box-sizing: border-box;" /># 8 = Unknown<br style="box-sizing: border-box;" /># 9 = Unknown<br style="box-sizing: border-box;" /># 10 = Unknown<br style="box-sizing: border-box;" /># 11 = Unknown<br style="box-sizing: border-box;" /># 12 = Unknown<br style="box-sizing: border-box;" /># 13 = Unknown<br style="box-sizing: border-box;" /># 14 = Unknown<br style="box-sizing: border-box;" /># 15 = Unknown<br style="box-sizing: border-box;" /># 255 = 自动检测 (默认)<br style="box-sizing: border-box;" />DBC.Locale = 255<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 启用GM命令记录-所有的SQL代码都将被记录在日记文件中<br style="box-sizing: border-box;" /># All commands are written to a file: YYYY-MM-DD_logSQL.sql<br style="box-sizing: border-box;" /># If a new day starts (00:00:00) then a new file is created - the old<br style="box-sizing: border-box;" /># file will not be deleted.<br style="box-sizing: border-box;" /># 0 - 不记录<br style="box-sizing: border-box;" /># 1 - 记录<br style="box-sizing: border-box;" />LogSQL = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 服务器控制台记录显示的级别<br style="box-sizing: border-box;" /># 0 = 最小; 1 = 基础和错误; 2 = 详细; 3 = 完全或侦错<br style="box-sizing: border-box;" /># 默认: 0<br style="box-sizing: border-box;" /># 推荐: 1<br style="box-sizing: border-box;" />LogLevel = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 记录文件 的名字<br style="box-sizing: border-box;" /># 文件名为空 则不创建记录文件,如: LogFile =&nbsp;<br style="box-sizing: border-box;" /># 默认: ""<br style="box-sizing: border-box;" />LogFile = "Server.log"<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># Logfile with timestamp of server start in name<br style="box-sizing: border-box;" /># Default: 0 - no timestamp in name<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />LogTimestamp = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 记录文件的记录级别<br style="box-sizing: border-box;" /># 0 = 最小; 1 = 基础和错误; 2 = 详细; 3 = 完全或侦错<br style="box-sizing: border-box;" /># 默认: 0<br style="box-sizing: border-box;" />LogFileLevel = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># Log filters<br style="box-sizing: border-box;" /># 0 (default) - include in log if log level permit, 1 - not include with any log level<br style="box-sizing: border-box;" />LogFilter_TransportMoves = 0<br style="box-sizing: border-box;" />LogFilter_CreatureMoves = 0<br style="box-sizing: border-box;" />LogFilter_VisibilityChanges = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 控制台信息的颜色 (格式: "正常颜色 详情颜色 debug颜色 错误颜色)<br style="box-sizing: border-box;" /># 颜色: 0-黑色, 1-红, 2-绿, 3-棕, 4-蓝, 5-品红, 6-青绿, 7-灰色,&nbsp;<br style="box-sizing: border-box;" /># 8-黄, 9-淡红, 10-淡绿, 11-淡蓝, 12-淡品红, 13-淡青绿, 14-白色<br style="box-sizing: border-box;" /># 默认: "" 无颜色(白色)<br style="box-sizing: border-box;" /># 例如: "13 7 11 9"&nbsp;<br style="box-sizing: border-box;" />LogColors = "13 7 11 9"<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># Packet logging file for the worldserver.<br style="box-sizing: border-box;" /># Default: ""<br style="box-sizing: border-box;" />WorldLogFile = "world.log"<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 记录数据库错误的文件名<br style="box-sizing: border-box;" /># 默认: ""<br style="box-sizing: border-box;" />DBErrorLogFile = "DBErrors.log"<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 记录GM命令使用情况的 记录文件名<br style="box-sizing: border-box;" /># 默认: "" (禁止) 允许时:例如: "GMcommand.log"<br style="box-sizing: border-box;" />GmLogFile = ""<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># Log file of RA commands, "" for disable<br style="box-sizing: border-box;" /># Default: "Ra.log"<br style="box-sizing: border-box;" />RaLogFile = ""<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 在多线程系统 使用线程MASK(只在Windows系统下使用)<br style="box-sizing: border-box;" /># 默认: 0 (操作系统来选择)<br style="box-sizing: border-box;" /># 举例: 数字<br style="box-sizing: border-box;" />UseProcessors = 80<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 进程优先权设置(只在Windows系统下使用)<br style="box-sizing: border-box;" /># 0 (正常优先权)<br style="box-sizing: border-box;" /># 默认: 1 (高优先)<br style="box-sizing: border-box;" />ProcessPriority = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#发送到客户端的更新数据包的压缩级别(1到9)<br style="box-sizing: border-box;" /># 默认: 1 (速度快,不压缩)&nbsp;<br style="box-sizing: border-box;" /># 9 (最好的压缩)&nbsp;<br style="box-sizing: border-box;" />Compression = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 除GM之外 游戏最大在线玩家数限制<br style="box-sizing: border-box;" /># 默认: 100<br style="box-sizing: border-box;" />PlayerLimit = 100<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 玩家获得经验能升到的最高等级(必须在 1 到 255).<br style="box-sizing: border-box;" /># 不建议修改 建议用默认的 60 超过60 可能影响游戏平衡<br style="box-sizing: border-box;" /># 默认: 60<br style="box-sizing: border-box;" />MaxPlayerLevel = 70<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 天气系统开关<br style="box-sizing: border-box;" /># 默认: 1 (开)<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 0 (关)<br style="box-sizing: border-box;" />ActivateWeather = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 是否忽略进入副本的等级需要<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; 1 (true)<br style="box-sizing: border-box;" /># 默认: 0 (否)<br style="box-sizing: border-box;" />IgnoreATLevelRequirement = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 玩家最多可以学的 商业技能<br style="box-sizing: border-box;" /># 默认: 2<br style="box-sizing: border-box;" /># 最大: 9<br style="box-sizing: border-box;" />MaxPrimaryTradeSkill = 2&nbsp;<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 建立公会所需的最少玩家签名个数 (0..9).<br style="box-sizing: border-box;" /># 默认: 9<br style="box-sizing: border-box;" />MinPetitionSigns = 9<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 小队成员在生物死亡 获得经验的 最大距离(同怪物的距离)<br style="box-sizing: border-box;" /># 默认: 74<br style="box-sizing: border-box;" />MaxGroupXPDistance = 74<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 小队成员在生物死亡 获得经验的 最大等级差(同怪物的等级)<br style="box-sizing: border-box;" /># 默认: 10<br style="box-sizing: border-box;" />MaxGroupXPLevelDiff = 10<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 是否运行同1个帐号 建立不2个不同阵营的角色 GM号为始终为 允许<br style="box-sizing: border-box;" /># 默认: 0 (不允许)<br style="box-sizing: border-box;" /># 1 (允许)<br style="box-sizing: border-box;" />AllowTwoSide.Accounts = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 是否允许 不同阵营间的 聊天 频道聊天 组队 交易<br style="box-sizing: border-box;" /># 默认: 0 (不允许)<br style="box-sizing: border-box;" /># &nbsp;&nbsp;&nbsp; 1 (允许)<br style="box-sizing: border-box;" />AllowTwoSide.Interaction.Chat = 0<br style="box-sizing: border-box;" />AllowTwoSide.Interaction.Channel = 0<br style="box-sizing: border-box;" />AllowTwoSide.Interaction.Group = 0<br style="box-sizing: border-box;" />AllowTwoSide.Interaction.Guild = 0<br style="box-sizing: border-box;" />AllowTwoSide.Interaction.Trade = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 是否在 在线玩家列表 里显示敌对阵营玩家<br style="box-sizing: border-box;" /># 默认: 0 (不允许)<br style="box-sizing: border-box;" /># 1 (允许)<br style="box-sizing: border-box;" />AllowTwoSide.WhoList = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 防刷屏开关,多少条违规信息激活保护<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 0 (为关闭防刷屏)<br style="box-sizing: border-box;" /># 默认: 10<br style="box-sizing: border-box;" />ChatFlood.MessageCount = 10<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 防刷屏开关,多少秒间隔开始计算为违规信息<br style="box-sizing: border-box;" /># 默认: 1 (秒)<br style="box-sizing: border-box;" />ChatFlood.MessageDelay = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 防刷屏开关,禁言时间.<br style="box-sizing: border-box;" /># 默认: 10 (秒)<br style="box-sizing: border-box;" />ChatFlood.MuteTime = 10<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># GM默认是否接受玩家的悄悄话.<br style="box-sizing: border-box;" /># 默认: 0 (false)<br style="box-sizing: border-box;" /># &nbsp;&nbsp;&nbsp; 1 (true)&nbsp;<br style="box-sizing: border-box;" />GM.WhisperingTo = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 当GM设置为可见时 是否在玩家列表显示GM.<br style="box-sizing: border-box;" /># 默认: 0 (false)<br style="box-sizing: border-box;" /># &nbsp;&nbsp;&nbsp; 1 (true)&nbsp;<br style="box-sizing: border-box;" />GM.InGMList = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 是否显示GM名单 (if visible).<br style="box-sizing: border-box;" /># 默认: 0 (false)<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 1 (true)&nbsp;<br style="box-sizing: border-box;" />GM.InWhoList = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># GM模式在登陆时状态<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 0 (总是关)<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 1 (总是开)&nbsp;<br style="box-sizing: border-box;" /># 默认: 2 (上次离开时状态)<br style="box-sizing: border-box;" />GM.LoginState = 2<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 如果打开 则在GM LOG里记录GM的交易和交易信息<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 0 (不记录)<br style="box-sizing: border-box;" /># 默认: 1 (记录)<br style="box-sizing: border-box;" />GM.LogTrade = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 团队可见模式<br style="box-sizing: border-box;" /># 默认: 0-标准设置：只有同一个团队的队友才可以100%侦测隐形玩家<br style="box-sizing: border-box;" /># &nbsp;&nbsp; 1-只有同一个小队的队友才可以100%侦测隐形玩家<br style="box-sizing: border-box;" /># &nbsp;&nbsp; 2-同一阵营的队友可以100%侦测隐形玩家<br style="box-sizing: border-box;" />Visibility.GroupMode = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 不同的游戏物体之间的可见度&nbsp;<br style="box-sizing: border-box;" /># 最大设置: ~ 166<br style="box-sizing: border-box;" /># 最小设置以物体为准<br style="box-sizing: border-box;" /># 默认: 66 (单元)<br style="box-sizing: border-box;" />#<br style="box-sizing: border-box;" /># Min limit is max aggro radius (45) * Rate.Creature.Aggro<br style="box-sizing: border-box;" />Visibility.Distance.Creature &nbsp;&nbsp; = 66<br style="box-sizing: border-box;" />Visibility.Distance.Player &nbsp;&nbsp; &nbsp;&nbsp; = 66<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># gameobject, dynobject, bodies, corpses, bones<br style="box-sizing: border-box;" /># Min limit is iteraction distance (5)<br style="box-sizing: border-box;" />Visibility.Distance.Object &nbsp;&nbsp; &nbsp;&nbsp; = 66<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># visible distance for player in flight<br style="box-sizing: border-box;" /># Min limit is 0 (not show any objects)<br style="box-sizing: border-box;" />Visibility.Distance.InFlight &nbsp;&nbsp; = 66<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># Visibility grey distance for creatures/players (fast changing obects)<br style="box-sizing: border-box;" /># &nbsp;&nbsp;&nbsp; addition to appropriate object type Visibility.Distance.* use in case visibility removing to object (except corpse around distences)<br style="box-sizing: border-box;" /># &nbsp;&nbsp;&nbsp; If ?is distance and G is grey distance then object make visible if distance to it &lt;= D but make non visible if distance &gt; D+G<br style="box-sizing: border-box;" /># Default: 1 yard<br style="box-sizing: border-box;" />Visibility.Distance.Grey.Unit = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># Visibility grey distance for dynobjects/gameobjects/corpses/creature bodies<br style="box-sizing: border-box;" />#&nbsp;<br style="box-sizing: border-box;" /># Default: 10 yards<br style="box-sizing: border-box;" />Visibility.Distance.Grey.Object = 10<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 如果邮寄物品延时多久收到？？<br style="box-sizing: border-box;" /># 默认: 3600 秒 (1 hour)<br style="box-sizing: border-box;" />MailDeliveryDelay = 3600<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 每日消息。当玩家进入游戏的时候显示在聊天窗口的信息。<br style="box-sizing: border-box;" />Motd = "Welcome to the Massive Network Game Object Server."<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># Health and power regeneration and rage income from damage.<br style="box-sizing: border-box;" />Rate.Health = 1;<br style="box-sizing: border-box;" />Rate.Mana = 1;<br style="box-sizing: border-box;" />Rate.Rage.Income = 1;<br style="box-sizing: border-box;" />Rate.Rage.Loss = 1;<br style="box-sizing: border-box;" />Rate.Focus = 1;<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 物品的掉率倍数<br style="box-sizing: border-box;" />#poor,白色；<br style="box-sizing: border-box;" />#common,普通；<br style="box-sizing: border-box;" />#uncommon,罕见的;<br style="box-sizing: border-box;" />#rare,贵重的；<br style="box-sizing: border-box;" />#Epic,史诗;<br style="box-sizing: border-box;" />#Legendary,传说;<br style="box-sizing: border-box;" />#uest,任务&gt;&nbsp;<br style="box-sizing: border-box;" /># 默认: 1<br style="box-sizing: border-box;" /># Rate.Drop.Items = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />Rate.Drop.Items.Quality.Poor = 1<br style="box-sizing: border-box;" />Rate.Drop.Items.Quality.Common = 1<br style="box-sizing: border-box;" />Rate.Drop.Items.Quality.Uncommon = 1<br style="box-sizing: border-box;" />Rate.Drop.Items.Quality.Rare = 1<br style="box-sizing: border-box;" />Rate.Drop.Items.Quality.Epic = 1<br style="box-sizing: border-box;" />Rate.Drop.Items.Quality.Legendary = 1<br style="box-sizing: border-box;" />Rate.Drop.Items.Quest = 1<br style="box-sizing: border-box;" />Rate.Drop.Money = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 杀怪,任务,探索地图 获得经验 乘以的倍数<br style="box-sizing: border-box;" /># 默认: 1<br style="box-sizing: border-box;" />Rate.XP.Kill &nbsp;&nbsp;&nbsp; = 20<br style="box-sizing: border-box;" />Rate.XP.Quest = 30<br style="box-sizing: border-box;" />Rate.XP.Explore = 10<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 普通,精英,稀有精英,BOSS,稀有普通怪 的伤害 乘以的倍数<br style="box-sizing: border-box;" /># 例如: 1.4 就是 增加0.4倍攻击伤害<br style="box-sizing: border-box;" />Rate.Creature.Normal.Damage = 1<br style="box-sizing: border-box;" />Rate.Creature.Elite.Elite.Damage = 1<br style="box-sizing: border-box;" />Rate.Creature.Elite.RAREELITE.Damage = 1<br style="box-sizing: border-box;" />Rate.Creature.Elite.WORLDBOSS.Damage = 1<br style="box-sizing: border-box;" />Rate.Creature.Elite.RARE.Damage = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 普通,精英,稀有精英,BOSS,稀有普通怪 的血量 乘以的倍数<br style="box-sizing: border-box;" /># 例如: 1.4 就是 增加0.4倍攻击血量<br style="box-sizing: border-box;" />Rate.Creature.Normal.HP = 1<br style="box-sizing: border-box;" />Rate.Creature.Elite.Elite.HP = 1<br style="box-sizing: border-box;" />Rate.Creature.Elite.RAREELITE.HP = 1<br style="box-sizing: border-box;" />Rate.Creature.Elite.WORLDBOSS.HP = 1<br style="box-sizing: border-box;" />Rate.Creature.Elite.RARE.HP = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" />#仇恨系数，默认1.1f，即有超过第一仇恨者造成伤害110%者就转变攻击对象。<br style="box-sizing: border-box;" />#注意！必须精确到小数点后1位<br style="box-sizing: border-box;" /># 默认: 1.1f<br style="box-sizing: border-box;" />AggroThreat = 1.1f<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 精力条增长倍数 (1 - normal, 2 - double rate, 0.5 - half rate, etc) from standard values<br style="box-sizing: border-box;" /># 游戏中<br style="box-sizing: border-box;" />Rate.Rest.InGame = 1<br style="box-sizing: border-box;" /># 在旅馆下线时<br style="box-sizing: border-box;" />Rate.Rest.Offline.InTavernOrCity = 1<br style="box-sizing: border-box;" /># 在野外下线时<br style="box-sizing: border-box;" />Rate.Rest.Offline.InWilderness = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 空中跌落伤害倍数<br style="box-sizing: border-box;" />Rate.Damage.Fall = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 拍卖 倍数<br style="box-sizing: border-box;" /># Rate.Auction.Time (拍卖时间倍率),Rate.Auction.Deposit(拍卖押金),Rate.Auction.Cut(拍卖上限)<br style="box-sizing: border-box;" />Rate.Auction.Time = 1<br style="box-sizing: border-box;" />Rate.Auction.Deposit = 1<br style="box-sizing: border-box;" />Rate.Auction.Cut = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 矿物 倍数<br style="box-sizing: border-box;" />#Rate.Mining.Next (采矿的几率倍数),Rate.Mining.Amount (产生矿最大最小的倍数)<br style="box-sizing: border-box;" />Rate.Mining.Amount = 1<br style="box-sizing: border-box;" />Rate.Mining.Next = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 天赋点的升级倍率<br style="box-sizing: border-box;" /># 默认: 1<br style="box-sizing: border-box;" />Rate.Talent = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 保存刷新时间 当生物死 当物体被打开或使用<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 0 (保存人/物体的刷新时间在网格卸载的时候)<br style="box-sizing: border-box;" /># 默认: 1 (不在网格卸载的时候保存人/物体的刷新时间)<br style="box-sizing: border-box;" />SaveRespawnTimeImmediately = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 技能熟练度提升几率(0..100)&nbsp;&nbsp;<br style="box-sizing: border-box;" /># 默认: 100-75-25-0<br style="box-sizing: border-box;" />SkillChance.Orange = 100<br style="box-sizing: border-box;" />SkillChance.Yellow = 75<br style="box-sizing: border-box;" />SkillChance.Green = 25<br style="box-sizing: border-box;" />SkillChance.Grey = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 怪物自动攻击的范围乘以的倍数 或者 关闭自动攻击<br style="box-sizing: border-box;" /># 0 - 关闭(0%)<br style="box-sizing: border-box;" /># 默认: 1 - 乘以100%&nbsp;<br style="box-sizing: border-box;" /># 1.5 - 乘以150%<br style="box-sizing: border-box;" />Rate.Creature.Aggro = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 控制台开关<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 0 - 关<br style="box-sizing: border-box;" /># 默认: 1 - 开<br style="box-sizing: border-box;" />Console.Enable = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 远程控制台开关<br style="box-sizing: border-box;" /># 默认: 0 - 关<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 1 - 开<br style="box-sizing: border-box;" />Ra.Enable = 0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 默认远程控制IP地址,0.0.0.0为所有IP皆可.<br style="box-sizing: border-box;" />Ra.IP = 0.0.0.0<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 默认远程控制台端口<br style="box-sizing: border-box;" />Ra.Port = 3443<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 远程控制台连接到服务器所需要的GM等级，默认为3（管理员）<br style="box-sizing: border-box;" />Ra.MinLevel = 3<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 踢出用户，如果他输入了错误的密码 （仅限远程控制台）<br style="box-sizing: border-box;" />Ra.Secure = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 最大速度限制倍率<br style="box-sizing: border-box;" /># 默认: 2 如果为0则关闭检查加速<br style="box-sizing: border-box;" />MaxOverspeedPings = 2<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 卸载Grids (如果里的内存够大,可以禁用,提高玩家第二次经过新Grids时候的速度)<br style="box-sizing: border-box;" /># P.S: Grids就是地图上刷出来的东西,玩家经过一个地方 就会加载该地方的环境,离开的时候 就卸载该地方的环境<br style="box-sizing: border-box;" /># 默认: 1 ( 卸载 grids) 0 ( 不卸载 grids)<br style="box-sizing: border-box;" />GridUnload = 1;<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 以下所有的时间设置都以毫秒为单位。<br style="box-sizing: border-box;" /># 默认端口选择时间<br style="box-sizing: border-box;" />SocketSelectTime = 10000<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 默认地图网格清理延迟<br style="box-sizing: border-box;" />GridCleanUpDelay = 300000<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 默认地图更新间隔<br style="box-sizing: border-box;" />MapUpdateInterval = 100<br style="box-sizing: border-box;" /># 默认天气更新间隔<br style="box-sizing: border-box;" />ChangeWeatherInterval = 600000<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 默认玩家数据保存间隔<br style="box-sizing: border-box;" />PlayerSaveInterval = 900000<br style="box-sizing: border-box;" /># 默认世界服务器端口 mangosd.exe 的端口）<br style="box-sizing: border-box;" />WorldServerPort = 8085<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 在mangos启动完毕后蜂鸣一声(通常只在Unix nux系统下工作)<br style="box-sizing: border-box;" /># 默认: 1<br style="box-sizing: border-box;" />BeepAtStart = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 打开/关闭 VMmap 对视线和高度的推算支持<br style="box-sizing: border-box;" /># Default: 1 (true)<br style="box-sizing: border-box;" /># &nbsp;&nbsp; &nbsp;&nbsp; : 0 (false)<br style="box-sizing: border-box;" />vmap.enableLOS = 1<br style="box-sizing: border-box;" />vmap.enableHeight = 1<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 不使用 VMap功能的地图ID<br style="box-sizing: border-box;" /># 地图ID之间用 ','分割<br style="box-sizing: border-box;" /># 如果有多个地图ID使用 "号包含<br style="box-sizing: border-box;" />#vmap.ignoreMapIds = "369,0,1,530"<br style="box-sizing: border-box;" />#DeeprunTram 没有包含在地图中<br style="box-sizing: border-box;" />vmap.ignoreMapIds = "369"<br style="box-sizing: border-box;" /><br style="box-sizing: border-box;" /># 不进行视线推算的技能<br style="box-sizing: border-box;" /># 技能之间使用 ','分割<br style="box-sizing: border-box;" />vmap.ignoreSpellIds = "7720"</div></div></td></tr></tbody></table><img src ="http://www.cppblog.com/ming81/aggbug/214497.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ming81/" target="_blank">点点滴滴</a> 2016-12-16 11:16 <a href="http://www.cppblog.com/ming81/archive/2016/12/16/214497.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(搬运工)CritterAI官方文档翻译【An Introduction to NMGen】</title><link>http://www.cppblog.com/ming81/archive/2016/11/08/214398.html</link><dc:creator>点点滴滴</dc:creator><author>点点滴滴</author><pubDate>Tue, 08 Nov 2016 13:18:00 GMT</pubDate><guid>http://www.cppblog.com/ming81/archive/2016/11/08/214398.html</guid><description><![CDATA[<span style="font-family: Arial; color: #333333; background-color: #ffffff"><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">The purpose of NMGen is to generate navigation meshes from arbitrary source geometry. Features fall into two categories: Core and 'standard build'.</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">NMGen用于将任意网格转化为一个或多个NavMesh。 其所有功能都包含于两个目录： Core(核心) 和 'standard build'(普通);</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">The core features are located in the org.critterai.nmgen namespace and involve creating simplified polygon mesh data from detailed triangle-based source geometry. You can code your own build process from scratch using these features, but it will require a significant amount of work and detailed knowlege of all aspects of the process.</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">核心功能位于nmgen命名空间下，与将复杂的三角形mesh转化为简化的多边形mesh有关。你可以通过代码彻底重新规划生成过程(1)，不过这里有很多事情要做，而且你需要了解生成过程中各个方面的实现细节(2)。</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">The standard build process implements a flexible, extendable build process suitable for use at design time. It takes care of many of the mundane details for you. Its features are implemented in the following namespaces:</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">Common extentions: org.critterai.nmbuild</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">Unity extensions: org.critterai.nmbuild.u3d.editor</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">普通生成流程为了满足编辑期的需要，被设计成可变的、可扩展的结构。它已经为你处理好了很多细枝末节的事情(3)。普通功能位于以下的命名空间中：</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">通用扩展(3): nmbuild</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">Unity扩展: nmbuild.u3d.editor</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">The standard build process has three main steps which will be covered in detail throughout the rest of this section.</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">Compile the input.</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">The NMGen Build. (Produces the polygon meshes.)</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">Create the navigation mesh.</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">普通生成流程有如下三个主要步骤，稍后的章节会对这三个步骤进行详细的介绍。</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">编译数据源.</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">调用NMGen的生成功能(生成多边形网格).</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">生成 Navigation Mesh.(导航网格)</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">Note Note:</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">CAINav uses the OpenGL coordinate system.</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">注意：</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">CAINav使用OpenGL坐标系统.(XYZ,左右手什么的);</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">(1)生成过程有哪些？</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">(2)哪些方面的细节需要了解？</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">(3)相对于recast的扩展,cai是基于recast的功能基础而实现的;</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">快速扫盲</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">1、A* Path Finding是一个图最短路径搜索算法，只要数据源支持"遍历邻居"的操作，就可以应用A*;</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">2、Ploygen Mesh 是凸多边形网格，因为凸多边形内任意两点可以直达--在满足指定的倾斜角(slope limit)和高度差(step height)的情况下。</span><br style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" /><span style="font-size: 14px; font-family: Arial; white-space: normal; text-transform: none; word-spacing: 0px; float: none; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; display: inline !important; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal">3、如果有地形的Triangle Mesh,其实已经可以基于它进行A*了，因为三角形也是凸多边形。大费周章的使用Nav Mesh是为了1、大幅简化图的复杂度，将不必要的信息进行合并。2、记录一些额外的信息，比如 xxx xxx。</span></span><img src ="http://www.cppblog.com/ming81/aggbug/214398.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ming81/" target="_blank">点点滴滴</a> 2016-11-08 21:18 <a href="http://www.cppblog.com/ming81/archive/2016/11/08/214398.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(搬运工)  CritterAI官方文档翻译【The Crowd Manager】</title><link>http://www.cppblog.com/ming81/archive/2016/11/08/214397.html</link><dc:creator>点点滴滴</dc:creator><author>点点滴滴</author><pubDate>Tue, 08 Nov 2016 13:17:00 GMT</pubDate><guid>http://www.cppblog.com/ming81/archive/2016/11/08/214397.html</guid><description><![CDATA[<span style="font-family: Arial; color: #333333; background-color: #ffffff">
<div id="article_content" class="article_content" style="white-space: normal; text-transform: none; word-spacing: 0px; color: rgb(51,51,51); text-align: left; font: 14px/26px Arial; margin: 20px 0px 0px; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; font-stretch: normal; -webkit-text-stroke-width: 0px">The crowd manager is the big beast of the navigation components. It not only handles a lot of the path management for you, but also local steering and dynamic avoidance between navigation clients. I.e. It can keep your agents from running into each other.<br />【CrowdManager】类是十分庞杂的一个类。它不仅为你处理了非常多的路径管理相关的事情，同时也处理一些局部转向和避开其它寻路代理对象。也就是说，他可以让所有的代理对象不会相互穿插。<br /><br /><br />Core Class: CrowdManager<br />核心类：CrowdManager<br /><br /><br />The NavmeshQuery and PathCorridor classes provide perfectly good, easy to use path planning features. But in the end they only give you points that your navigation client should be moving toward. When it comes to deciding things like client velocity and steering to avoid other clients, that is up to you to implement. Unless, of course, you decide to use the crowd manager.<br />NavmeshQuery和PathCorridor这两个类已经很不错了，用来做路径规划也足够简单。但是说到底它们只是给了你一堆指导角色运动的路点。当你决定实现一些角色之间不发生碰撞的特性时，只能你自己实现了。除非，当然，你决定使用CrowdManager。<br /><br /><br />Basically, you add an navigation client (agent) to the crowd manager, providing various configuration settings such as maximum speed and acceleration. You also provide a local target to more toward. The crowd manager then provides, with every update, the new agent position and velocity for the frame. The movement will be constrained to the navigation mesh, and steering will be applied to ensure agents managed by the crowd manager do not collide with each other.<br />基本上来讲，你可以往CrowdManager添加一个角色，同时提供一些配置数据，例如最大速度和加速度。你也可以提供一个局部的目标(让角色自主的移动过去(1))。然后CrowdManager会在每帧更新的时候设置角色的最新位置和速度。运动会被约束在Navmesh内，CrowdManager会让角色在需要的时候进行转向，以确保不会相互碰。<br /><br /><br />This is very powerful feature set. But it comes with limitations.<br />The biggest limitation is that you must give control of the agent's position and velocity completely over to the crowd manager. You can update things like maximum speed and acceleration. But in order for the crowd manager to do its thing, it can't allow you to constantly be giving it overrides to position and velocity. So you give up direct control of the agent's movement. It belongs to the crowd manager.<br />The second biggest limitation revolves around the fact that the crowd manager deals with local planning. The agent's target should never be more than 256 polygons aways from its current position. If it is, you risk your agent failing to reach its target. So you may still need to do long distance planning and provide the crowd manager with intermediate targets.<br /><br /><br />这是一个非常强大的特性集。但是它伴随着一些限制。<br />最大的限制在于你必须将角色的位置和速度完全交给CrowdManager来控制。你可以更新类似最大速度和加速度之类的参数。但是为了让CrowdManager能正常工作，你不能经常的改变角色的位置和速度。因此你需要放弃管理角色运动。这个工作现在属于CrowdManager。<br /><br /><br /><br /><br />Other significant limitations:<br />All agents using the crowd manager use the same NavmeshQueryFilter.<br />Crowd management is relatively expensive. The maximum agents under crowd management at any one time is around 20.<br /><br /><br />其他明显的限制<br />所有托管的角色都使用同样的查询过滤器<br />人群管理的开销相对较大。可以管理的人群的个体数量最大约为20个(1)。<br /><br /><br />The Sample Pack includes a Crowd Manager Demo that lets you see the manager in action.<br /><br /><br /><br /><br />(1)需要实验?<br />(1)这个数量是一个人为的限制，可以通过修改代码突破此限制。</div>
<div class="bdsharebuttonbox tracking-ad bdshare-button-style0-16" style="font-size: 12px; font-family: Arial, Console, Verdana, 'Courier New'; white-space: normal; text-transform: none; word-spacing: 0px; zoom: 1; float: right; font-weight: normal; color: rgb(51,51,51); font-style: normal; text-align: left; orphans: 2; widows: 2; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px; font-variant-ligatures: normal; font-variant-caps: normal" data-bd-bind="1478611370148" data-mod="popu_172"><a class="bds_more" style="cursor: pointer; font-size: 12px; height: 16px;background-image: url(http://bdimg.share.baidu.com/static/api/img/share/icons_0_16.png?v=d754dcc0.png); background-repeat: no-repeat; background-position: 0px 0px; float: left; color: rgb(51,51,51); padding-left: 17px; text-decoration: none; margin: 6px 6px 6px 0px; line-height: 16px" href="http://blog.csdn.net/kun1234567/article/details/41714389#" target="_blank" data-cmd="more"></a><a title="分享到QQ空间" class="bds_qzone" style="cursor: pointer; font-size: 12px; height: 16px;background-image: url(http://www.cppblog.com/ming81/img/share/icons_0_16.png?v=91362611.png); background-repeat: no-repeat; background-position: 0px -52px; float: left; color: rgb(51,102,153); padding-left: 17px; text-decoration: none; margin: 6px 6px 6px 0px; line-height: 16px" href="http://blog.csdn.net/kun1234567/article/details/41714389#" target="_blank" data-cmd="qzone"></a><a title="分享到新浪微博" class="bds_tsina" style="cursor: pointer; font-size: 12px; height: 16px;background-image: url(http://www.cppblog.com/ming81/img/share/icons_0_16.png?v=91362611.png); background-repeat: no-repeat; background-position: 0px -104px; float: left; color: rgb(51,102,153); padding-left: 17px; text-decoration: none; margin: 6px 6px 6px 0px; line-height: 16px" href="http://blog.csdn.net/kun1234567/article/details/41714389#" target="_blank" data-cmd="tsina"></a><a title="分享到腾讯微博" class="bds_tqq" style="cursor: pointer; font-size: 12px; height: 16px;background-image: url(http://www.cppblog.com/ming81/img/share/icons_0_16.png?v=91362611.png); background-repeat: no-repeat; background-position: 0px -260px; float: left; color: rgb(51,102,153); padding-left: 17px; text-decoration: none; margin: 6px 6px 6px 0px; line-height: 16px" href="http://blog.csdn.net/kun1234567/article/details/41714389#" target="_blank" data-cmd="tqq"></a><a title="分享到人人网" class="bds_renren" style="cursor: pointer; font-size: 12px; height: 16px;background-image: url(http://www.cppblog.com/ming81/img/share/icons_0_16.png?v=91362611.png); background-repeat: no-repeat; background-position: 0px -208px; float: left; color: rgb(51,102,153); padding-left: 17px; text-decoration: none; margin: 6px 6px 6px 0px; line-height: 16px" href="http://blog.csdn.net/kun1234567/article/details/41714389#" target="_blank" data-cmd="renren"></a><a title="分享到微信" class="bds_weixin" style="cursor: pointer; font-size: 12px; height: 16px;background-image: url(http://www.cppblog.com/ming81/img/share/icons_0_16.png?v=91362611.png); background-repeat: no-repeat; background-position: 0px -1612px; float: left; color: rgb(51,102,153); padding-left: 17px; text-decoration: none; margin: 6px 6px 6px 0px; line-height: 16px" href="http://blog.csdn.net/kun1234567/article/details/41714389#" target="_blank" data-cmd="weixin"></a></div></span><img src ="http://www.cppblog.com/ming81/aggbug/214397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ming81/" target="_blank">点点滴滴</a> 2016-11-08 21:17 <a href="http://www.cppblog.com/ming81/archive/2016/11/08/214397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(搬运工) CritterAI官方文档翻译【The Path Corridor】</title><link>http://www.cppblog.com/ming81/archive/2016/11/08/214396.html</link><dc:creator>点点滴滴</dc:creator><author>点点滴滴</author><pubDate>Tue, 08 Nov 2016 13:16:00 GMT</pubDate><guid>http://www.cppblog.com/ming81/archive/2016/11/08/214396.html</guid><description><![CDATA[<span style="color: #333333; font-family: Arial; background-color: #ffffff;">The Path Corridor</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">翻译：kun 2014.12.4</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The path corridor provides a way of moving along a navigation path without worrying about the minutiae of managing the path.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">廊道提供了一种沿指定导航路径进行移动，而不必担心管理使用路径数据时的细节问题。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Core Class: PathCorridor</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">核心类：PathCorridor</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">In the simplest scenario, a path is a list of waypoints from a starting point to an end point. The waypoints form a connected set of line segments along which a navigation client moves. But&nbsp;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">navigation is much more complex in the real world. There are locomotion limitations, local steering restrictions, dynamic obstacle avoidance, and good old floating point errors. All of these&nbsp;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">issues can make management of a path difficult.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">在最简单的情景里，一个路径是一组从开始点到结束点的路点列表。如果能精确的按照使用此导航数据运动，角色的轨迹会是一组相互连接的线段。但是在真实环境下进行导航比这个要复杂的多。你需要考虑角色的运</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">动能力的局限性(1)、局部转向限制、避开动态障碍物、以及一些常见的浮点数错误。所有这些情况都会让管理一个路径的使用变得困难。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Navigation based on a polygon mesh provides a different abstraction than just a list of waypoints. The path returned by the NavmeshQuery class is a list of polygons. Technically, a client can&nbsp;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">move freely anywhere within this corridor of polygons. If a client strays outside the corridor, then the corridor can be patched up using local searches rather than full path replanning.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">在一个多边形网格上进行导航比在一堆路点上进行导航要更加抽象一些。NavmeshQuery返回的Path是一组多边形。技术上讲，一个角色可以在这个廊道上的任意多边形内自由的移动。如果一个角色跑出了这个廊道的范</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">围，廊道的范围可以使用局部搜索进行扩大，而不是重新规划整条路径。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The path corridor is loaded with a path, a start point, and a target point. It is then used to move the navigation client through the corridor. It handles path straightening, constraining the&nbsp;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">client to the navigation mesh, and adjusting the corridor due to inaccurate client locomotion.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">廊道需要加载一个Path、一个起始点、一个目标点。然后用于角色在这个廊道内移动。它处理路径的矫正、确保角色不会跑出Navmesh、以及当角色移动超出预期时修正廊道信息。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The PathCorridor API is well documented. The only thing worth repeating here is a warning: You can't just initialize a corridor with a path and forget long distance path planning. Since the&nbsp;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">path corridor class uses local searches to maintain the corridor, attempting to apply large delta movement to the corridor's position or target can result in a malformed corridor. Details are&nbsp;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">in the API documentation.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">PathCorridor API已经有详细的文档说明了。在这里只有一点值得提一下：你不能只创建一个廊道然后一切都交给它去做，而不进行长路径规划。虽然廊道使用了局部搜索来维持廊道完整性，不过如果在廊道里产生一</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">个大的运动距离，或者目标点离得很远，会产生一个畸形的廊道(1)。更多的细节可以参考相关API文档。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">(1)加速、减速、惯性之类的运动参数.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">(2)啥意思?</span><img src ="http://www.cppblog.com/ming81/aggbug/214396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ming81/" target="_blank">点点滴滴</a> 2016-11-08 21:16 <a href="http://www.cppblog.com/ming81/archive/2016/11/08/214396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(搬运工)CritterAI官方文档翻译【The Navigation Query】</title><link>http://www.cppblog.com/ming81/archive/2016/11/08/214395.html</link><dc:creator>点点滴滴</dc:creator><author>点点滴滴</author><pubDate>Tue, 08 Nov 2016 13:15:00 GMT</pubDate><guid>http://www.cppblog.com/ming81/archive/2016/11/08/214395.html</guid><description><![CDATA[<p style="color: #333333; font-family: Arial; background-color: #ffffff;"><span style="line-height: 26px;">翻译：kun 2014.12.4</span><br /></p><p style="color: #333333; font-family: Arial; background-color: #ffffff;">The navigation mesh query is the most important class to understand since most navigation clients will interact with the query rather than the navigation mesh itself. The mesh contains the data, but the query provides almost all of the features necessary for pathfinding.<br />用户和navigation mesh query(Navmesh查询器)打交道的次数比Navmes本身多的多。网格包含数据，但是查询器提供了几乎全部的寻路特性。</p><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Core Class: NavmeshQuery</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">核心类：NavmeshQuery</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Query features fall into two general categories: Pathfinding and local search.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">查询器的特性包括两个大的方面：寻路和局部搜索。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Pathfinding involves standard A* and Dijkstra searches that find the best path(s) between two points. Paths are made up of a list polygon references that represent a polygon corridor from the start to the end position. Path straightening is used to convert the path into a list of waypoints. (I.e. String pulling.)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">寻路使用标准的A*和Dijkstra算法，用于找出两点之间最好的路径(可能不止一条)。Path(路径)是由一组Polygon的引用(1)组成数据，从开始点到结束点。路径矫正是将一个Path数据转为一组路点数据(即String pulling(绳子拉直))(2)。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The local search features offer various methods for locating polygons and points on polygons, and for querying the local environment. I.e. Raycasting, finding the distance to the nearest wall, etc.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">局部搜索功能提供多种方式进行多边形和多边形上的点的定位，以及查询局部的一些环境信息。比如射线查询、计算离最近的墙的距离之类的。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Many of the query methods require a NavmeshQueryFilter. Filters define area traversal costs as well as flags used for including/excluding polygons and off-mesh connections from results.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">许多查询方法要求一个NavmeshQueryFilter(查询过滤器)。过滤器定义了Polygon和off-mesh connections的穿越代价，代价值可以参与启发式的计算，用来决定是否在最终路径里包含/排除某个Polygon或off-mesh connections。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The best way to understand the query class is to play around with it. The Sample Pack includes the Query Explorer demo that permits experimentation with all of the main query features.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">理解查询器的最好办法就是用一用。【Sample Pack(示例包)】里的【Query Explorer(查询演示)】demo展示了查询器一些主要的特性。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Common Operations</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">通用操作</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">This section contains some simple examples of common query operations.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Finding a Point in the Navigation Mesh</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">You can't do much without first getting a valid point on the navigation mesh. So the first step is to find one.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">GetNearestPoint(Vector3, Vector3, NavmeshQueryFilter, NavmeshPoint)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">本节是例子</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">查询一个在Navmesh上的点</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">如果你没有一个Navmesh上的起始点的话，你能做的不多。所以第一部就是找一个点。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">GetNearestPoint(Vector3, Vector3, NavmeshQueryFilter, NavmeshPoint)函数提供此功能。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">CopyC#</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// Where 'query' is a NavmeshQuery object and 'filter' is a NavmeshQueryFilter object.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// 'position' is a Vector3 indicating the world position of the client.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// 'query'是一个 NavmeshQuery对象，'filter'是一个NavmeshQueryFilter对象。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// 'position' 是一个Vector3对象，值为角色的世界坐标。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">NavmeshPoint result;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Vector3 extents = new Vector3(1, 1, 1); &nbsp;// Keep this to the minimum extents practical. // 范围越小越好。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">NavStatus status = query.GetNearestPoly(position, extents, filter</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; , out result);</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">if (result.polyRef == Navmesh.NullPoly)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">{</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; // Handle error. &nbsp;Could not find a result.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; // The status can be checked to see if there was an error. &nbsp;If not, then</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; // the cause is that the search extents did not overlap any polygons.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; // 错误处理。找不到结果。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; // 可以检查状态看看是什么问题。如果没有问题，说明指定范围里不包含多边形。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">}</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// Use the result point, which includes a vector point and the reference of&nbsp;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// the polygon that contains the point.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">//使用结果点。包括一个Vector3的点和包含这个点的Polygon的引用。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Basic Pathfinding</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Even if you are planning to use PathCorridor or CrowdManager, you'll always need to do long distance planning using the basic NavmeshQuery features. First, get a path, then optionally straighten it.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">基础的寻径</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">即使你打算使用pathcorridor或crowdmanager,你也会需要NavmeshQuery的功能来完成一些长距离路径规划。第一，获取一条路径，然后选择性的弄直它(3)。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">CopyC#</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// Where 'query' is a NavmeshQuery object and 'filter' is a NavmeshQueryFilter object.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// 'start' and 'end' are NavmeshPoints known to be on the navigation mesh.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// 'query'是一个 NavmeshQuery对象，'filter'是一个NavmeshQueryFilter对象;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// 'start' 和 'end' 是已知的在Navmesh上的点;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">int pathCount;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// The path will be a list of polygon references.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// path是一组polygon的引用;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">uint[] path = new uint[100]; &nbsp;// Size for maximum allowed path length. // 路径的最大长度;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">NavStatus status;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">if (start.polyRef == end.polyRef)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">{</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; // No need to do any planning.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; // 开始点和结束点在同一个多边形内，不需要进行路径规划;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; pathCount = 1;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; path[0] = start.polyRef;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">}</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">else</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">{</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; status = query.FindPath(start, end, filter, path</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , out pathCount);</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; if (NavUtil.Failed(status) || path.pathCount == 0)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; {</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Handle pathfinding failure.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 处理寻路失败;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; }</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; else if (end.polyRef != path[pathCount - 1])</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; {</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Handle a partial path.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // The query either could not reach the end point,</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // or the path buffer was too small to hold the</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // entire path. &nbsp;(A check of 'status' will reveal if</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // the buffer was too small.)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 处理只有一部分路径的情况;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 可能是结束点不可达;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 或者路径的buffer长度太小，装不下整条路径;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 如果是buffer太小，可以检查state;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; }</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">}</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// If you need to straighten the path...</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// 如果你需要拉直路径;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">const int MaxStraightPath = 4; &nbsp;// Just getting the first 4 waypoints. // 只处理前4个路点;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">int wpCount;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// The waypoints.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// 路点列表;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Vector3[] wpPoints = new Vecotr3[MaxStraightPath];</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// A list of polygon references. &nbsp;(The polygon being entered at each waypoint.)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// 一个多边形引用列表;(路点是多边形的入口点)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">uint[] wpPath = new uint[MaxStraightPath];</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// The type of each waypoint. (Start, end, off-mesh connection.)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// 每一个路点的类型信息.(开始点，结束点, 连接);</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">WaypointFlag[] wpFlags = new WaypointFlag[MaxStraightPath];</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">status = query.GetStraightPath(start.point</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; , goal.point</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; , path</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; , 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// The index of the start of the path. // 路径的开始点;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; , pathCount &nbsp; &nbsp; &nbsp; &nbsp;// The length of the path. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 路径的长度;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; , wpPoints</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; , wpFlags</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; , wpPath</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; , out wpCount);</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">if (NavUtil.Failed(status) || wpCount == 0)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">{</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; // Handle the failure. &nbsp;There should always be at least one waypoint&nbsp;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; // (the goal) for a valid point/path combination,</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; // 处理失败。应该总是存在一个点(目标点)用于路径合并.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">}</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// Use the path and waypoints.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">// 使用路径和路点;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">(1)可以理解为句柄，或索引。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">(2)Path上每个多边形中心之间的连线一般不会是直线，路径如果有拐角也会造成一些美观上的问题，这个时候需要使用特定的方法将路径变得尽量笔直，就好像将一根绳子拉直。</span><img src ="http://www.cppblog.com/ming81/aggbug/214395.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ming81/" target="_blank">点点滴滴</a> 2016-11-08 21:15 <a href="http://www.cppblog.com/ming81/archive/2016/11/08/214395.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(搬运工)CritterAI官方文档翻译【The Navigation Mesh】</title><link>http://www.cppblog.com/ming81/archive/2016/11/08/214394.html</link><dc:creator>点点滴滴</dc:creator><author>点点滴滴</author><pubDate>Tue, 08 Nov 2016 13:14:00 GMT</pubDate><guid>http://www.cppblog.com/ming81/archive/2016/11/08/214394.html</guid><description><![CDATA[<span style="color: #333333; font-family: Arial; background-color: #ffffff;">The Navigation Mesh</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">翻译：kun 2014.12.4&nbsp;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The navigation mesh is the primary data model for the navigation system. The only user component that deals directly with the mesh on a regular basis is the component that is responsible for creating the mesh and managing its state. Normal navigation clients, the one's needing to perform pathfinding and such, rarely if ever interact directly with the navigation mesh.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">NavigationMesh是导航系统的主要数据模型。用户只需要创建导航网格数据和维护数据状态。需要使用导航的地方一般是进行寻路操作，偶尔也可以使用navmesh进行一些交互。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Core Class: Navmesh</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">核心类：Navmesh</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The Data Model</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">数据模型</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Tiles</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">At the core of the navigation mesh is the tile. Tiles hold the vast majority of structural and state information. In fact, the Navmesh class is little more than a tile manager. It may consist of a single tile, or many tiles laid out in a grid that can be swapped in and out at runtime.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The tile based structure of the navigation mesh adds a lot of flexibility. As mentioned, tiles can be swapped in and out at runtime. This means that the mesh can represent a large area, but not all tiles have to be loaded and active, reducing the mesh's memory footprint. This also allows for a situation where individual tiles can be rebuilt without the need to rebuild the entire mesh.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Tiles(片区)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Navmesh的核心概念之一就是Tile。Tiles存放了大多数的结构信息和状态信息。事实上，Navmesh类有点像一个TileManager。Navmesh可以由单个Tile构成，也可以向网格一样的平铺开来，以便在运行期动态的替换其中的某个Tile。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Structural Elements</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The tile's structural data is what defines the navigation graph used for pathfinding. It consists of two types of elements: Polygons and off-mesh connections.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The core of the structure is a mesh of convex polygons with between three and MaxAllowedVertsPerPoly vertices. This mesh is in the same format as NMGen's PolyMesh structure, and usually represents an abstraction of a scene's static geometry.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Off-mesh connections are optional. They consist of two connected endpoints, at least one of which resides within a polygon in the polygon mesh. Off-mesh connections are added to the navigation graph as a single edge and represent special travel routes not defined by scene geometry. Think: The route an agent travels if it jumps over a railing that normally blocks movement.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">节点元素</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Tile的数据结构是一个用于寻路的graph(图)。它由两种数据结构组成：Polygons(多边形集合)和off-mesh connections(分离的网格之间的连接关系集合)。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Off-mesh connections(分离的网格之间的连接关系集合)可以没有。它由两个相互连接的端点构成，至少一边在某个多边形里。Off-mesh connections作为单独的边添加到图的数据结构里。它代表着一种特殊的行走路线，并且不是由原始场景的几何体生成的。想象一下，一个角色跳过一个栏杆-栏杆可以阻碍普通的前进。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">State Data</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Tiles also contain state data. This data is associated with individual polygons and off-mesh connections. State data includes area and flags.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Areas are used to associate traversal cost to structural elements. This effects pathfinding. For example, the area representing swampland can have a higher cost than the area representing smooth surfaces such as meadowland.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Flags can be used to control when a structural element is traversable. For example, a flag can be set on the polygon below a door to indicate that it is closed and locked. Or a flag can indicate that only agents of a particular type are allowed to traverse the element.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">It is important to note that areas and flags have no meaning within the navigation mesh itself. The interpretation of the values is dependant on the NavmeshQueryFilter used by each navigation client. For example: One filter may define a cost of 10 for area id 5, while another may define a cost of 2 for the same area. One flag may be set when a door is closed with one filter checking for the flag during pathfinding, while another filter, used by a ghost, ignores the flag completely.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">状态</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Tile包括了一些状态信息。状态用来区分不同的Polygons和off-mesh connections。状态数据包括areas(区域信息)和flags(标志位)。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Areas(区域)一般用来定义移动代价的。代价影响寻路。举个例子，穿越被标记为沼泽的区域时的代价花费可能比穿越标记为草地的区域的代价要高。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Flags(标志位)可以用来控制一个节点的可行走属性。举个例子，一个作为'门'的多边形，在门关闭的时候，可以给这个多边形设置一个特殊的标志位，以表示它是不可通过的。或者设置一个特殊的标志位，只允许特定类型的角色通过。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Areas和Flags的意义不是由Navmesh定义的，这非常重要。这些特别指定的数字都是由导航系认的用户系统自定义的NavmeshQueryFilter来解释的。举个例子：一个过滤器认为ID为5的区域具有10点路径代价，而另一个过滤器则认为只有2的路径代价。当一个关闭的门的标志位被设置后(1)，一种过滤器在寻路的时候就会考虑这种情况而将这个门视为不可通过，另外一种过滤器-可能是用于鬼魂的寻路-就会完全忽略这个标志位而将此节点认为是可通过的。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Structure Versus State</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Why is it important to know the difference between structural elements and state data?</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The first reason is that it is possible to save and load state separately from structure. One common use case is to have a serialized version of the full navigation mesh that represents its default state. Then serialized versions of various states, such as the last runtime state, are used to overwrite the default state as needed.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The main limitation is that a state is only valid for a particular structure. So you can't, for example, save the state, change the tile structure, then load the original state into the new structure.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The second reason for understanding the difference between structure and state has to to with tile and polygon references...</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">结构VS状态</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">节点元素和状态之间进行了分离，理解这点非常重要。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">首先，这样它们可以独立的进行保存和加载。一个通常的情况是，加载一个预制的Navmesh数据后，其中的状态可能都是默认值，而利用一个上一次运行时保存的串行化的状态缓存，可以覆盖原始的状态信息。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">不过这里有一个限制，状态信息和节点自身是精确匹配的。你不能在更改完一个节点的信息后，又将一个老的状态赋给它。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">第二点则是对Tile和Polygon的引用方式。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Tile and Polygon References</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The last bit of information needed to understand the navigation mesh is the concept of tile and polygon references. These values are one of the few data types that are defined by the navigation mesh rather than the tiles within the mesh. It is important to understand what references are because they are used by various classes to automatically invalidate pathfinding data if the structure of a navigation mesh changes.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Essentially, tile and polygon references are unsigned integer 'handles' to structural elements within a navigation mesh. Tile references are rarely used by navigation clients, while polygon references are all over the place. Polygon references are unique for the navigation mesh, so they are useful for easily identifying a polygon without needing to know which tile it belongs to.&nbsp;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Despite the name, polygon references can refer to a either a polygon or an off-mesh connection.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">References can become invalid. If they are used after they are invalidated, then methods will return a failure status. Polygon references are based on the tile reference. So they will be invalidated whenever their associated tile reference is invalidated.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Structural changes govern the life of a reference. Changing the configuration of a navigation mesh or the internal structure of a tile will invalidate all associated references.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">References are preserved during tile state changes such as changes flags and areas. They are also preserved during normal runtime loading and unloading of tiles, and during normal serialization/de-serialization of a navigation mesh.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Tile和Polygon的引用方式</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">要完全理解Navmesh，最后一点信息是关于Tile和Polygon的引用这个概念。这些引用是Navmesh为数不多的数据结构之一，而不是由Tile定义的。理解引用是什么很重要，因为通过它可以实现当导航网格发生变化的时候，一些类似寻路功能的模块能自动的将引用的多边形置为无效。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">本质上来说，Tile和Polygon的引用是一个uint32(无符号整型)。Tile的引用很少被客户代码直接使用，因为使用场合基本上都可以被Polygon代替。Navmesh里的每个Polygon的引用都是唯一的，因此它们能够非常方便的定位到指定的Polygon，而不需要知道这个Polygon属于哪个Tile。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">虽然名字差别比较大，Polygon的引用概念同时也涵盖了off-mesh connections对象。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">引用可以变成无效的。如果在无效之后还使用引用，函数会返回一个失败信息。Polygon的引用有效性是基于Tile的引用的。因此当Tile的引用无效了，所有属于Tile的Polygon的引用也会无效。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">构造的变化会影响引用的生命周期。改变Navmesh的配置或者Tile的内部结构会引起相关的引用全部失效。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">引用会在Tile的状态发生变化的时候进行保存，比如指定Area或Flag值的时候。在运行期动态的加载或卸载Tile也会使引用自动保存，还有当正常串行化/反串行化一个Navmesh的时候。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Creating a Navigation Mesh</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">There are various pipelines for creating a navigation mesh. If you are using Unity, the Unity extensions make it easier. Otherwise, the basic steps are as follows:</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Generate packed tile data:</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Generate PolyMesh and PolyMeshDetail data using NMGen.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Optionally create a ConnectionSet. (Off-mesh connections.)</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Load the data into a NavmeshTileBuildData object.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Create a NavmeshTileData object from the build data.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The tile's structure and default state is now locked into a packed data format that is ready to be loaded into a navigation mesh.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">创建一个Navigation Mesh</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">创建一个Navmesh有一些流程。如果你在使用Unity，那么CAI提供的Unity扩展会让这件事情稍微简单点。否则，基本流程如下：</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">生成打包好的Tile数据.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">使用NMGen生成PolyMesh和PolyMeshDetail。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">创建个ConnectionSet(Off-mesh connections的容器)，这是可选的。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">将这些数据(tile,PolyMesh,PolyMeshDetail,ConnectionSet)加载到NavmeshTileBuildData对象里。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">创建一个NavmeshTileDatad数据。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">现在Tile的构成关系和默认状态已经都封装到NavmeshTileData里了，并且为生成Navmesh而做了数据结构的改变。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Note Note:</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Using the NavmeshTileBuildData class directly can be a bit daunting. The GetBuildData(BuildContext, Int32, Int32, PolyMeshData, PolyMeshDetailData, ConnectionSet, Boolean) utility method provides a standard way of&nbsp;</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">creating the build data.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">注意：</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">直接使用NavmeshTileBuildData类可能有点难搞。GetBuildData这个工具函数提供了一种标准流程。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Create a navigation mesh:</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Single tile navigation meshes are created using the the single step Create(NavmeshTileBuildData, Navmesh) method.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Multi-tile navigation meshes are created then loaded using multiple methods. Use the Create(NavmeshParams, Navmesh) method to initialize an empty mesh. then add tile data using the AddTile(NavmeshTileData, UInt32, UInt32) method.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">创建一个Navmesh</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">如果创建只有个Tile的Navmesh,只需要调用一次Create(【NavmeshTileBuildData】, Navmesh)函数。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">创建多Tile的Navmesh需要多次调用函数。使用Create(【NavmeshParams】, Navmesh)函数创建一个空的navmesh,然后使用AddTile函数将Tile添加进去(1)。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Navigation Mesh Serialization</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">The Navmesh class supports byte serialization using the GetSerializedMesh() method. This saves the entire mesh.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">It is possible to serialize state separately from structure on a tile-by-tile basis. Get the tile from the mesh using the GetTile(Int32) method, then use the GetState(Byte[]) and SetState(Byte[]) methods.</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Navmesh的串行化</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">Namvesh类支持二进制串行化，使用GetSerializedMesh来完成。这会将整个mesh转成二进制数据。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">它可以每Tile的、状态和拓扑结构分离的进行串行化。从mesh里取Tile使用GetTile(Int32)函数，然后使用GetState(Byte[])函数和SetState(Byte[])函数进行状态的赋值。</span><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><br style="color: #333333; font-family: Arial; background-color: #ffffff;" /><span style="color: #333333; font-family: Arial; background-color: #ffffff;">(1)Tile数据有自己的生成流程，可以参考An Introduction to NMGen</span><img src ="http://www.cppblog.com/ming81/aggbug/214394.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ming81/" target="_blank">点点滴滴</a> 2016-11-08 21:14 <a href="http://www.cppblog.com/ming81/archive/2016/11/08/214394.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(搬运工)CritterAI官方文档翻译【An Introduction to Navigation】 </title><link>http://www.cppblog.com/ming81/archive/2016/11/08/214393.html</link><dc:creator>点点滴滴</dc:creator><author>点点滴滴</author><pubDate>Tue, 08 Nov 2016 13:13:00 GMT</pubDate><guid>http://www.cppblog.com/ming81/archive/2016/11/08/214393.html</guid><description><![CDATA[An Introduction to Navigation<br />翻译：kun 2014.12.4&nbsp;<br /><br /><br /> The navigation side of CAINav consists of features used to create and use navigation meshes for pathfinding and local steering.<br /> CAINav提供创建Navmesh、基于Navmesh的寻路和局部转向避障。<br /><br /><br />Core: org.critterai.nav<br /> Unity extensions: org.critterai.nav.u3d<br />核心命名空间：org.critterai.nav<br /> Unity扩展：org.critterai.nav.u3d<br /><br /><br /><br /><br /> There are five main classes you'll be dealing with:<br />经常和你打交道的类有五个：<br /><br /><br />Note Note:<br /> CAINav uses the OpenGL coordinate system.<br />注意：<br />CAINav使用OpenGL坐标系。<br /><br /><br />The Navmesh class defines the structure and state of the navigation mesh. The only user component that deals directly with this class on a regular basis is the component responsible for creating the mesh and managing its state. Normal navigation clients, the one's needing to perform pathfinding and such, rarely if ever interact directly with the navigation mesh.<br />【Navmesh】类定义了导航网格的数据结构和状态。这个类用于保存用户创建的导航网格数据和数据状态。需要使用导航的地方一般是进行寻路操作，偶尔也可以使用navmesh进行一些交互。<br /><br /><br />The most important class to understand and become comfortable with is the NavmeshQuery class. It provides almost all of the client navigation features, including A* and Dijkstra path searches, string pulling, point and polygon searches, raycasting, etc.<br />【NavmeshQuery】类是需要理解透彻的最重要的类。它提供了所有用户级的导航功能，包括使用A*算法和Dijkstra算法进行寻路、绳索牵引、搜索点和多边形、射线查询等等。<br /><br /><br />The NavmeshQueryFilter is a seemingly minor class, but it has a large impact on navigation. Filters are used to define the costs of traversing the mesh and flags that control which parts of the navigation mesh are included in operations. Multiple filters can be used to customize the navigation behavior on a per client basis.<br />【NavmeshQueryFilter】是一个看起来很小的类，但是它对导航的影响很大。过滤器用来定义穿过某个区域时的代价。可以使用多个过滤器来实现自定义的导航行为。<br /><br /><br />The PathCorridor class provides a way of moving along a navigation path without worrying about the minutiae of managing the path.<br />【PathCorridor】类提供了一种沿导航路径，而不必担心管理路径的细节(1)。<br /><br /><br />The CrowdManager is the big beast of the navigation classes. It not only handles a lot of the path management for you, but also local steering and dynamic avoidance between navigation clients. I.e. It can keep your agents from running into each other.<br />【CrowdManager】类是十分庞杂的一个类。它不仅为你处理了非常多的路径管理相关的事情，同时也处理一些局部避障和避开其它寻路代理对象。也就是说，他可以让所有的代理对象不会相互穿插。<br /><br /><br />(1)需要实验。&nbsp;<img src ="http://www.cppblog.com/ming81/aggbug/214393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ming81/" target="_blank">点点滴滴</a> 2016-11-08 21:13 <a href="http://www.cppblog.com/ming81/archive/2016/11/08/214393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(搬运工)五种开源协议的比较(BSD,Apache,GPL,LGPL,MIT)</title><link>http://www.cppblog.com/ming81/archive/2010/12/28/137615.html</link><dc:creator>点点滴滴</dc:creator><author>点点滴滴</author><pubDate>Tue, 28 Dec 2010 09:07:00 GMT</pubDate><guid>http://www.cppblog.com/ming81/archive/2010/12/28/137615.html</guid><description><![CDATA[<p>当Adobe、Microsoft、Sun等一系列巨头开始表现出对&#8221;开源&#8221;的青睐时，&#8221;开源&#8221;的时代即将到来！</p>
<p>最初来自：sinoprise.com/read.php?tid-662-page-e-fpage-1.html（遗憾的是这个链接已经打不开了），我基本未改动，只是进行了一些排版和整理。<br>参考文献：<a href="http://www.fsf.org/licensing/licenses/"><font color=#477725>http://www.fsf.org/licensing/licenses/</font></a></p>
<p>现今存在的开源协议很多，而经过Open Source Initiative组织通过批准的开源协议目前有58种（<a href="http://www.opensource.org/licenses/alphabetical"><font color=#477725>http://www.opensource.org/licenses/alphabetical</font></a>）。我们在常见的开源协议如BSD, GPL, LGPL,MIT等都是OSI批准的协议。如果要开源自己的代码，最好也是选择这些被批准的开源协议。</p>
<p>这里我们来看四种最常用的开源协议及它们的适用范围，供那些准备开源或者使用开源产品的开发人员/厂家参考。</p>
<p><strong>BSD开源协议（</strong><a href="http://www.fsf.org/licensing/licenses/index_html#OriginalBSD"><font color=#477725>original BSD license</font></a><strong>、</strong><a id=FreeBSD href="http://www.freebsd.org/copyright/freebsd-license.html" name=FreeBSD><font color=#477725>FreeBSD license</font></a><strong>、</strong><a id=OriginalBSD href="http://www.xfree86.org/3.3.6/COPYRIGHT2.html#6" name=OriginalBSD><font color=#477725>Original BSD license</font></a><strong>）</strong></p>
<p>BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以&#8221;为所欲为&#8221;,可以自由的使用，修改源代码，也可以将修改后的代码作为开源或者专有软件再发布。</p>
<p>但&#8221;为所欲为&#8221;的前提当你发布使用了BSD协议的代码，或则以BSD协议代码为基础做二次开发自己的产品时，需要满足三个条件：</p>
<ol>
    <li>如果再发布的产品中包含源代码，则在源代码中必须带有原来代码中的BSD协议。
    <li>如果再发布的只是二进制类库/软件，则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
    <li>不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。 </li>
</ol>
<p>BSD 代码鼓励代码共享，但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码，也允许使用或在BSD代码上开发商业软件发布和销售，因此是对商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议，因为可以完全控制这些第三方的代码，在必要的时候可以修改或者二次开发。</p>
<p><strong>Apache Licence 2.0（</strong><a href="http://www.apache.org/licenses/LICENSE-2.0"><font color=#477725>Apache License, Version 2.0</font></a>、<a href="http://www.apache.org/LICENSE-1.1"><font color=#477725>Apache License, Version 1.1</font></a>、<a href="http://www.apache.org/LICENSE-1.0"><font color=#477725>Apache License, Version 1.0</font></a><strong>）</strong></p>
<p>Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似，同样鼓励代码共享和尊重原作者的著作权，同样允许代码修改，再发布（作为开源或商业软件）。需要满足的条件也和BSD类似：</p>
<ol>
    <li>需要给代码的用户一份Apache Licence
    <li>如果你修改了代码，需要再被修改的文件中说明。
    <li>在延伸的代码中（修改和有源代码衍生的代码中）需要带有原来代码中的协议，商标，专利声明和其他原来作者规定需要包含的说明。
    <li>如果再发布的产品中包含一个Notice文件，则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可，但不可以表现为对Apache Licence构成更改。 </li>
</ol>
<p>Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。</p>
<p><strong>GPL（</strong><a id=GNUGPL href="http://www.fsf.org/licensing/licenses/gpl.html" name=GNUGPL><font color=#477725>GNU General Public License</font></a><strong>）</strong></p>
<p>我们很熟悉的Linux就是采用了GPL。GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用，但不允许修改后和衍生的代码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux，包括商业公司的linux和linux上各种各样的由个人，组织，以及商业软件公司开发的免费软件了。</p>
<p>GPL协议的主要内容是只要在一个软件中使用(&#8220;使用&#8221;指类库引用，修改后的代码或者衍生代码)GPL 协议的产品，则该软件产品必须也采用GPL协议，既必须也是开源和免费。<strong>这就是所谓的&#8221;传染性&#8221;</strong>。GPL协议的产品作为一个单独的产品使用没有任何问题，还可以享受免费的优势。</p>
<p>由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议，对于使用GPL协议的开源代码，商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。</p>
<p>其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似。</p>
<p><strong>LGPL（</strong><a id=LGPL href="http://www.fsf.org/licensing/licenses/lgpl.html" name=LGPL><font color=#477725>GNU Lesser General Public License</font></a><strong>）</strong></p>
<p>LGPL是GPL的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并发布和销售。</p>
<p>但是如果修改LGPL协议的代码或者衍生，则所有修改的代码，涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源代码很适合作为第三方类库被商业软件引用，但不适合希望以LGPL协议代码为基础，通过修改和衍生的方式做二次开发的商业软件采用。</p>
<p>GPL/LGPL都保障原作者的知识产权，避免有人利用开源代码复制并开发类似的产品</p>
<p><strong>MIT（<a href="http://www.opensource.org/licenses/mit-license.php"><font color=#477725>MIT</font></a>）</strong></p>
<p>MIT是和BSD一样宽范的许可协议,作者只想保留版权,而无任何其他了限制.也就是说,你必须在你的发行版里包含原许可协议的声明,无论你是以二进制发布的还是以源代码发布的.</p>
<img src ="http://www.cppblog.com/ming81/aggbug/137615.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ming81/" target="_blank">点点滴滴</a> 2010-12-28 17:07 <a href="http://www.cppblog.com/ming81/archive/2010/12/28/137615.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>