CritterAI插件CritterAI与RecastNavigation寻路 Unity中为⼀个GameObject添加导航信息 ⾸先,需要为GameObject添加⼀个NavMesh Agent(⽤于引导GameObject导航寻路,在component->Navigation中)
然后需要在对应的Terran或者Plane中,选择Navigation控件中进⾏Bake(烘焙)来产⽣导航⽹格路径
Unity中使⽤A(A star)与Dijsktra*最短路径算法结合来进⾏寻路转向等操作
Unity导航寻路
实际上Unity官⽅的导航寻路也是基于Recast Navigation并进⾏了深度改造,此开源库的作者于2013年已经加⼊了Unity Inc
项⽬
导航⽹格的⽣成
静态导航⽹格可以借助CritterAI插件在Unity中直接⽣成,这个⽐较简单,⽣成导航⽹格的相关参数配置
刹车马达
在下⾯的⽹格⽣成过程中的参数影响(Configuration Parameters)有详细说明,对照说明进⾏配置即可,⽣成的导航⽹格数据可以同时给客户端和服务器使⽤。
中子嬗变
真正的难点在于运⾏时的导航⽹格⽣成,具体做法和流程可以参见Recast Navigation的Demo,下⾯有详细介绍
基本寻路流程
Recast Navigation
该库使⽤⼗分⼴泛,Unity引擎官⽅的寻路,unreal的UDK的寻路均基于Recast Navigation开发的
关于动态障碍的问题
RecastNavigation在特定设置下可以⽀持动态⽹格⽣成的,也就是说可以直接使⽤RecastNavigation来做动态障碍,如何做,询问过RecastNavigation作者,他是这么回答的:
⽬前项⽬中现有的动态障碍使⽤的后⼀种⽅法,使⽤Tile Cache的⽅式实现的
RecastDetour
在RecastDetour⾥⾯有⼀个Sample_SoloMesh.cpp这样⼀个简单地demo,这个⽂件实现了如何建⽴导航⽹格的全部过程
在RecastDetour⾥⾯还有⼀个NavMeshTesterTool.cpp,这个⽂件则演⽰了如何使⽤前⾯建⽴的导航⽹格来进⾏寻路动作
Recast Demo
该Demo为⼀个综合性Demo,⾥⾯所演⽰的内容⼗分全⾯(其注释⼗分详尽),下⾯简要说明下⽬录结
构和主要⽂件,以及主要函数的功能,⽬前项⽬中所使⽤的导航以及导航⽹格⽣成动态障碍等等,其设计思想以及代码流程都是基于该Demo所提供的⽅案,所以说完全弄透这套代码基本导航⽹格寻路以及动态障碍就差不多了
⽬录结构
Bin //最终⽣成的可执⾏⽂件
Contrib //⼀些第三⽅DLL
English.lproj
Include
Source
Icon.icns
Info.plist
premake4.lua //premake4的lua配置脚本,⽤于⽣成VS2010⼯程等
screenshot.png陶瓷保险丝
主要⽂件
CrowdTool.cpp //管理实体移动寻路以及碰撞
NavMeshTesterTool.cpp // 演⽰Detour如何来寻路径,单纯的寻路径
Sample_SoloMesh.cpp //演⽰如何来⽣成导航⽹格
Sample_TempObstacles.cpp //演⽰如何添加临时障碍物对⽹格产⽣的影响,与动态障碍相关
关于Demo中的动态障碍
Demo中的动态障碍内容在Sample_TempObstacles.cpp,DetourTileCache.cpp,过程如下:
相关参考资料:
CritterAI
基于Recast Navigation制作,NMGen⽣成⽹格导航数据,⾄于如何使⽤这些导航数据,需要看Detour(a sister library of Recast),源码地址:
CAINav基本结构
The Navigation Mesh
即导航⽹格,为导航系统的基础数据模型
包含以下⼏个东西:
Tiles(导航块,包含了主要的结构和状态信息,导航块是基于具有可塑性的导航⽹格所构成的,能够在运⾏时进⾏变动,这意味着可以实现导航⽹格的动态变化)
Structural Elements(结构元素,两种,多边形和off-mesh connection)
State Data(状态信息,⽤于关联单个多边形和off-mesh connection,包含area和flags,area被⽤于关联在结构元素中通过所需的消耗,主要影响寻路。flags控制结构元素什么时候是可通过的。)
Tile and Polygon References(理解导航块和多边形引⽤是熟悉导航⽹格的关键(后⾯⽤T&P代指导航块和多边形引⽤),T&P本质上来说是⽆符号整形⽤于控制导航⽹格中的结构元素,T&P是可以⽤来唯⼀确定多边形或者off-mesh connection的标志,导航⽹格结构控制着T&P的⽣命周期,改变导航⽹格的配置或者导航块内部结构会导致T&P的⽆效,T&P可以在⼏种情况下保存下来:导航块状态改变时保留下来 运⾏时loading和unloading导航块时保留
导航⽹格在正常的序列化和反序列化期间)
⾄于如何⽣成导航⽹格,请参考最下⾯的更加具体的参考资料
The Navigation Mesh Query无尘布激光切割机
按照CAINAV⽂档的说法,这个是最重要最需要去熟悉理解的⼀个class,Navigation Mesh Query提供了⽤于pathfinding所必要的绝⼤多数特征信息
特征,取得的特征通常包含2⼤类:
Pathfinding
local search
寻路依然是基于标准A*与德加斯特拉最短路径算法(单源最短路径)
The Path Corridor
提供⼀个沿着导航路径⾛的移动⽅式
The Crowd Manager(CrowdManager)
简介:拥塞管理器是导航组件中最庞⼤的⼀个,它不仅仅需要处理路径管理,同时需要管理原地转向和动态碰撞避免
限制以及问题:
汽结构最⼤的限制在于你必须给定被控制的导航代理实体的position以及速率给crowd manager,你能够更新最⼤速度和最⼤加速度,但是为了能够让crowd manager去完成他⾃⼰的⼯作,它不会准许你不断地去覆盖他的位置和速率,也就是说你⽆法直接控制导航代理实体的移动,这个控制权在crowd manager。
第⼆个⽐较重要的限制是导航代理实体从⼀个当前的多边形位置到达⽬标多边形位置,中间所经过的多边形位置的数量不准许超过256个,如果你超过了,那么很有可能导航代理实体会导航失败⽆法到达指定⽬的地,解决办法在于在长距离导航路径中间加⼊中间⽬的地,说⽩了太长了⼀次不⾏,就分段处理(分治法)。
所有的导航代理实体使⽤相同的NavmeshQueryFilter
拥塞管理器⼗分消耗性能,拥塞管理器⼀次最多能够处理不超过20个导航代理实体
更加具体的参考资料:
关于CritterAI中的寻路算法A*
A*寻路算法本⾝资料⽐较丰富,就不做过多赘述,通常⽹上给的资料中的A*寻路适⽤于⽹格为⽅格⼦的情况,这⾥CritterAI中的⽹格为凸多边形(多为三⾓形)
参考资料:
⽹格⽣成过程中的参数影响(Configuration Parameters)
更加详细请参考:
cellSize
描述:> 0,设定体素(voxel)在X-Z-plane(OpenGL坐标系)上的⼤⼩,决定体素(voxel)在对原始⼏何图形进⾏采样时的精细度,值越⼩越精细,越⼤越粗略
影响:较⼩的值能够产⽣更加精确接近原始集合图形的⽹格,减少在⽣成导航⽹格过程中⽣成多边形产⽣较⼤偏离度的问题(详见NavMesh的过程的Generate Detailed Mesh),但是会消耗更加多的处理时间和内存占⽤,该设置为核⼼设置,会影响其他所有的参数设置
相关解释:
体素
cellHeight
描述:> 0,体素(voxel)在Y-plane(OpenGL坐标系)上的⼤⼩,决定体素(voxel)在对原始⼏何图形进⾏采样时的精细度,值越⼩越精细,越⼤越粗略,仅影响Y-Axis上的图形
影响:较⼩的值能够产⽣更加精确接近原始集合图形的⽹格,减少在⽣成导航⽹格过程中⽣成多边形产⽣较⼤偏离度的问题(详见NavMesh的过程的Generate Detailed Mesh,但是与cellSize不⼀样,较低的值并不会对内存消耗产⽣有显著影响),有⼀点需要注意,较低的值虽然能够使⽹格贴合原始图形,但是如果是凹凸不平的地形,较低的值可能会造成邻接的⽹格之间产⽣断裂,导致本来应该连在⼀起的⽹格造成分离
cellHeight设置较⾼时,可以看到⽹格和原始图形间距较⼤
cellHeight设置较⼩时,可以看到⽹格和原始图形贴合⽐较紧密
minTraversableHeight
描述:> 0, 最低可通过⾼度,设定从底部边界到顶部边界之间的最低⾼度,该⾼度为模型可通过的⾼度
影响:会影响场景中⼀些地形或者组件的可通过范围,⽐如桌⼦,如果设定值过低,会导致模型⾼度就算⾼过桌⼦也会从桌⼦中间传过去,设置过⾼会导致部分不被准许通过的场景也能穿过,另外⼀点,minTraversableHeight的设定值的⼤⼩⾄少得是cellHeight的2倍
当minTraversableHeight设置恰当时,⽹格不会跑到桌⼦下⾯去
当minTraversableHeight设置的值过低时,⽹格会跑到桌⼦下⾯去
maxTraversableStep
描述:> 0,可跨越不同地形时的⾼度,设定像是从普通平⾯移动到楼梯这样的地形是否可通过的⾼度阀值
影响:过低的值可能会导致⽆法通过原本可通过的地形,⽐如从平⾯到楼梯,导航⽹格⽣成时可能会发现楼梯的导航⽹格断裂缺失,导致⽆法楼梯寻路,设定值过⾼会导致原本不该通过的⼩物件能够被⾓⾊跨越,同样,值设定必须⼤于cellHeight的2倍
当maxTraversableStep设置的值⽐较恰当时,楼梯表⾯有⽹格⽣成
当maxTraversableStep设置的值过低时,楼梯表⾯没有⽹格⽣成
当maxTraversableStep设置的值过⾼时,结果不需要有⽹格的地⽅也会⽣成⽹格
maxTraversableSlope
描述:> 0,最⼤可通过的斜坡的倾斜度
影响:过低的值会导致⽆法通过原本可通过的地形
短程蒸馏器当maxTraversableSlope设置的值恰当时,⽹格能够延⽣到斜⾯上去