Get Started Part 2
A* Pathfinding Project 翻译第二波 Navmeshes 导航网格
第一部分教程中包括普通的导航图,以这为蓝本,第二部分使用自动生成的导航图重做,如果你对此感兴趣 请优先阅读第一部分的教程,其中包涵一些有用的信息。
Getting Started with the A* Pathfinding Project - Part 2 - Navmeshes.
The first part of this tutorial covers normal navmesh graphs, i.e those modelled by hand. The second part covers recast graphs which automatically generate navmeshes for you.
Even if you are only interested in the recast graphs, please read the first section as well since it covers some things which apply to recast graphs as well.
What is a navmesh?
什么是导航网格
在本教程的第一部分中,我们使用的网格图。但是A*寻路插件有不止一种类型的图支持,它还支持导航图。
网格图由排列呈网格的图组成,这种结构很实用,你也能通过网格图完成大部分的工作
在你得游戏中如果是个大型的草地,其中有小房子,为了表示足够的精度(你要利用网格标识出障碍) 这样做十分的浪费节点
这时引进Nvameshes,Navmeshes 使用多边形标识(更具体的描述是三角形),就如果你游戏的mesh(模型的网格)
总结一句话~ Navmeshes 被用来准确描述表面的可行走区域 PS:我怎么觉得像是废话呢 ,下面进入正题了 前面的废话只是个引子
In the first part of this tutorial we used the Grid Graph. But the A* Pathfinding Project has support for more than one type of graphs, it also supports navmesh graphs.
A GridGraph consists of a bunch of nodes arranged in a grid-like pattern, it is very structured and thus works for most things you throw at it. But doesn't it feel like a waste of nodes to generate a huge number of nodes for your large open grass field you are using in your game, just to be able to get enough precision to represent the small obstacles around the farmers house (or whatever). Wouldn't it be better to use a few nodes to represent the large field and then more nodes for the smaller obstacles. This is where navmeshes come in. Navmeshes represent the world using polygons (more specifically triangles in this case), much like other meshes you have in your game. Navmeshes are used to accurately describe the surface that the character(s) can walk on.
正如你所见的的,上图中并未有完全对等大小的节点(多边形),但是你可以随心所欲的改变节点的大小。最终的结果就是导航网格与网格图相比不需要浪费空白区域的节点,它更小更快 通常可以快速的执行寻路。同时相对于普通的网格来说它可以执行多层次的环境中寻路,当然需要Pro版本的支持(需要付钱),此特性在Pro版本的LayeredGridGraph。
那么导航图有什么缺点呢~ 生成导航图比较慢大概 100-200毫秒 这取决于你的电脑,更新导航图上的哪怕很小的物体都很慢。
Like you see in the above image, the navmesh does not have equally sized nodes, but nodes can be as large or as small as you want them to be. The end result is that navmeshes can more accurately describe the environment and are smaller because they do not need to waste a large number of nodes on empty areas. Because they are smaller, they are also usually faster to perform pathfinding on. Also, they can represent multilayered environments as opposed to normal grid graphs (but which is a feature of the LayeredGridGraph available in the pro version).
So what are the downsides? The main problem with navmesh graphs is that they take a long time to generate (or model, if you do it by hand). To scan a whole GridGraph as in the GridGraph example scene takes something like 100-200 ms (depending on the computer), to generate a recast graph (back to them later) easily takes a few seconds. They are also relatively static: when you have generated it, it is quite slow to update it, even just a very small part of the graph. With the RecastGraph, it is possible to do limited fast updating of the graphs using navmesh cutting , and full graph updates in small parts of the graph (relatively slow).
Creating a navmesh
创建导航图 导航图可以手动或自动生成,自动生成只在付费的版本中。
本教程中我们假定这样的场景,一个BOX在Plane中间
Navmeshes can be modelled by hand, or automatically generated. The automatic generation is only available in the pro version and is described later in this tutorial.
Assume we had this scene: A simple plane with a box in the middle.
建一个模型网格,打开你喜欢的建模软件(我喜欢用Blender)
创建一个平面,分两步 移除四个面
To model a navmesh, open up you favourite modelling application (I will use Blender).
Create a plane, subdivide it two times and then remove the inner four quads.
Blender将展示四周,但是当导出到Unity时,它将转换为A*寻路使用的三角形。
导出为FBX文件在你的项目中
Blender will show quads, but when exporting to Unity, it will be converted into the triangles that the A* Pathfinding uses.
Export to an FBX file somewhere in your project.
现在他应该在Unity中显示出来了。
创建一个新GameObject,如第一个教程,叫它“A*”(在层次面板中比较容易找到)然后田间的Pathfinder脚本。然后打开 Graphs -> Add Graph -> Navmesh Graph。你将创建一个新的导航图,打开他设置。
Now it should show up in Unity.
Create a new GameObject, like in the first tutorial, name it "A*" (to find it easily in the heirarchy) and attach the "Pathfinder" component. Then open Graphs -> Add Graph -> Navmesh Graph. This will create a new navmesh graph, open the settings for it.
拖动网格对象(不是Prefab对象) 是导入的带有Soure图标的FBX文件 拖到navmesh graph 。如有有问题你找一下修复的按钮(fix buttons),由于使用的序列化技术问题,你必须将对象命命名为模型网格的名字,点击fix按钮 自动会做这件事。
点击Scan按钮(或cmd-alt-s)。如果一切顺利,你会看到在场景视图中的网格。然而你可能需要改一下导入FBX文件的Sclar 导入的Sclar是0.1你改成1。同时根据你使用的建模工具的不同你可能需要旋转你的模型。你可以在导航图中设置旋转,旋转(- 90,0,0)这时候就对了。
现在按下扫描应该显示你在场景中显示图。为了确保图是显示的(在监视面板的底部 需要勾选)。
Drag the mesh object (not the prefab object) which was imported before to the "Source" field on the navmesh graph. It will probably show some fix buttons. Due to technical serialization issues, the meshes need to be placed in the Resources folder and the object must be named the same as the actual mesh. Clicking the fix buttons will do this for you.
Press Scan (or Cmd-Alt-S). If everything goes well, you will see the mesh in the scene view. However you might need to change the import scale on the mesh (in the import settings for the mesh asset), usually Unity defaults to an import scale of 0.01, change this to 1. Also depending on the axis settings your modelling tool uses, you might need to rotate it. You can rotate it directly in the navmesh graph settings. When importing from blender with default settings, rotating with (-90, 0, 0) will give it the correct rotation.
Now pressing scan should show you the graph in the scene view. Make sure Show Graphs (at the bottom of the inspector, is checked).
在前面的教程中,我们写了一个简单的脚本,用于移动人物控制器。我们可以使用前面教程的脚本但是为了获得更好的体验我们使用另一个脚本。它被称为RichAI。创建一个新的GameObject 附加RichAI组件。它会自动附加一个Seeker。为了可视化的目的,添加一个胶囊对象作为子对象的根节点。将胶囊设置为一个单元,GameObject 节点作为胶囊的根节点,RichAI附着在人物控制器的父节点上。
你要注意移除胶囊的碰撞与其他物体的碰撞。或者自行配置Mask剔除碰撞。为什么要做样做呢?因为RichAI组件用的是射线检测。它还支持charactercontroller,但我不推荐,因为角色控制器相对较慢。
创建另一个Gameobect为“目标”。分配对象到RichAI组件的Target字段上。这样RichAI的路径会重新计算,否则它会等待一个移动命令,但没有什么脚本告诉它移动。
In the previous tutorial we wrote a simple script for moving a character around. We could use the same script, but to get nicer movement I will introduce an included component which gives very nice movement on navmeshes (specifically navmeshes). It is called RichAI. Create a new GameObject and attach the RichAI component to it. It will automatically attach a Seeker. For visualization purposes, add a Capsule object as a child object to root. Move the capsule one unit up, so that the root GameObject will have its pivot point at the capsule's base, the RichAI script assumes that the pivot is at the feet of the character.
Take care that you remove the capsule collider (and any other colliders) from the character. Or you need to configure the mask field on the RichAI component to exclude those colliders. Why? Because the RichAI component by default uses raycasting to determine where the ground is, and if that raycast hit a collider which was attached to itself, you would see wodd behaviour (try for yourself). It also support a CharacterController, but I do not recommend that because character controllers are relatively slow.
Create another GameObject named "Target". Assign that object to the Target field on the RichAI component. Also enable continous Path Recalculation on the RichAI, otherwise it will just wait for a move order, but there is no other script telling it to move.
现在,当你按下Play按钮你可以看到胶囊向目标移动。当移动目标对象时候胶囊应该跟随它。
RichAIi脚本是专门为导航图上的移动写的。它要求代理(胶囊)一直处于导航的状态。与此项目中的其他运动脚本相反,它不支持路径修饰脚本。这是因为它不遵循列表的航点,而是遵循一个节点列表。这样做的好处是,即使路径没有计算角色也可以摆到场景里。
描述RichAI 设定的教程太多的,这里有文档:RichAI
Now when pressing play you should see the agent moving towards the target. When moving the target object around, the agent should follow it.
The RichAI script is specially written for movement on navmesh graphs. It enforces that the agent stays on the navmesh at all times. As opposed to other movement scripts in this project, it does not have support for path modifiers. This is because it does not follow a list of waypoints, instead it follows a list of nodes. This has the advantage that the character can be pushed around by some amount and it will still move correctly without a path recalculation.
Describing every setting for the RichAI is too much for this tutorial, you can find documentation for it here: RichAI.
Notes about navmesh graphs
关于导航图的注意事项
当不使用RichAIi组件时,具有简化后的路径,建议将funnel修饰脚本添加到Seeker附着的GameObject上。funnel修饰脚本将简化路径,使它更美观(更短)。
请参阅
funnelmodifier
有时候给出的不是最优的路径。这是应为寻路在三角的中心进行。这大多发生在导航已经非常大和非常小的节点(三角形)拼在一起。寻路的时候则喜欢优先选择更小的三角形(有时选择较大的三角形的一个,但不常见)。
When not using the RichAI component, which has build in path simplification, it is recommended to attach the f vunnel modifier to the GameObject with the Seeker. The funnel modifier will simplify the path and make it much more aesthetically pleasing (and also shorter).
- See Also
- FunnelModifier
Navmesh graphs can sometimes give suboptimal paths. This is because pathfinding is carried out on node (triangle) centers. It happens mostly when the navmesh has very large and very small nodes (triangles) placed close to each other. The pathfinding then usually prefers the path with smaller triangles (sometimes the one with larger triangles, but not as common).
如上图所示,找到的路径是绿色的,它穿过了浅橙色的节点。实际最短路径显示红色,它穿过在浅红色节点。
世上万能的解药。尽量避免非常大的三角形靠近小的三角。见下图 你可以将一个较大的三角形拆成较小的。降低最大的边长
In the above image, the found path is shown in green, the nodes it passes through in pale orange. The actual shortest path is shown in red, with the nodes it passes through in pale red.
There is no silver bullet for this. Try to avoid very large triangles close to small ones. For recast graphs (see below), you can specify a lower tile size to split up very large triangles into smaller ones. And the Max EdgeLength can be lowered as well.
Recast Graphs
Recast 图
注意
Recast 是Pro版本可用的。
Recast 图可以自动生成导航,节省了你很多宝贵的工作时间。你可以删除以前创建的导航图,添加一个Recast 图代替。
- Note
- The Recast Graph is only available in A* Pathfinding Project Pro (not to be confused with Unity Pro, it can be used in Unity Free as well).
A recast graph can automatically generate the navmesh, saving you many precious hours of work. You can remove the previously created navmesh graph and add a recast graph instead.
后面有空再翻译 这一章节没有我想要的解决方案 2015.9.06 Keyle
The recast graph works by taking all your meshes in your scene (that's the polygons, not the colliders, though that can be enabled as well) and voxelize it, a 2D analogue for voxelization would be like taking a bunch of triangles and drawing them on a texture, textures are made up of pixels, 3D pixels are called voxels. Then a walkable navmesh is generated from settings like character height, radius and similar.
Scanning the graph directly will most likely not give you any good results. First, press the Snap Bounds To Scene button. It will find all meshes in your scene and configure the graph's bounds to enclose them. You can also specify the bounds manually. The bounds is visualized by a white wire-cube in the scene view.
The width and depth values will probably be too low. Those fields are not directly editable, instead you have to edit the cell size (size of each voxel) to modify it. For this scene, I have set cell size to 0.1, and since our plane is 10 units wide, and the graph encloses it precisely, the number of width and depth samples will be 100. You can also set cell height to a similar value. If that is too high, there will not be enough precision to represent small y-coordinate changes. Next, set tile size to 100. A recast graph uses tiles to divide the graph into square chunks. Setting it to the same as our width/depth gives us a single tile for the whole mesh. Usually you can do that and it will give you better navmeshes. But a lower tile size can be good when updating a recast graph (less to update) or to divide up huge polygons in a number of smaller ones to avoid suboptimal paths (more on that later).
Pressing scan now should give you something like this: (you can compare your settings to mine)
It is often nice to have Show Mesh Outline enabled in the recast graph settings.
Almost everything looks good. The only problem is that our character has also been included in the navmesh, we don't want that (since the character will move around, it is not static). So we place the character in a separate layer (e.g Transparent FX) and then we configure the Layer Mask field on the recast graph to exclude that layer in navmesh generation.
Pressing play should now give you a scanned graph and the character should move to the target.
Notes about Recast Graphs
The resolution of the recast graph (the width/depth fields in the inspector) have a large effect on how the generated navmesh looks. The image below shows the same environment, but with different resolution for the voxelization. Note that the thin region between the cubes is only walkable when a high enough resolution was set.
Rasterization resolution has a great effect on the time it takes to generate a recast graph, but it has no direct impact on the runtime performance of it (except of course, full graph updates). Indirectly it can affect it slightly since a large resolution can add more detail to the graph.