UE——导航系统(NavigationSystem)

一、基本导航

  1. 构建导航网格
    拖拽NavMeshBoundsVolume到关卡内。

自动更新导航网格: 在 编辑器设置(Editor Settings)->Level Editor->Miscellaneous-> 启用自动更新导航(Update Navigation Automatically)。


  1. 可视化导航网格
    关卡中找到RecastNavMesh-Default,并在Detail里勾选Draw Poly EdgesDraw Tile Bounds

Draw Poly Edges: 绘制组成网格的多边形。
Draw Tile Bounds: 可视化单个Navigation Tiles

在这里插入图片描述

二、修改导航网格

1.使用Navigation Modifier Volumes

AreaClass应用于导航网格,用于更改体积空间内多边形的属性以修改其通过成本。
在这里插入图片描述

Area Class描述
NavArea_Default默认情况下,将相同的导航成本分配给体积内的区域和导航网格。
NavArea_LowHeight代表一个区域符合低高度通过条件,防止Agent通过它。导航网格不会在该体积内生成导航数据。
NavArea_Null表示体积内的空白区域。 导航网格不会在该体积内生成导航数据。
NavArea_Obstacle为体积内的区域分配高导航成本。如果有通路走通路,没通路才会走这条路

2.使用Nav Link Proxy

2.1 连接两个导航区域

Nav Link Proxy连接导航网格中两个不相连的导航区域。 在搜索路径时,Nav Link Proxy用作Agent到达其目的地的额外连接。指示代理在没有可用的连续导航路径时可以从平台跌落或跳向目标。
在这里插入图片描述

Note: 如果 Nav Link Proxy 未与 Navigation Mesh 的表面连接,黑色箭头将消失。(在UE4里是绿色箭头)
黑色箭头是实际AI的导航路径


2.2 修改连接方向

SimpleLink里,可以修改连接方向。
在这里插入图片描述

2.3 使用SmartLink

使用SmartLink,让Agent跳到高处
在这里插入图片描述
逻辑:
在这里插入图片描述
在这里插入图片描述

Warning: Nav Link Proxy只能连接相邻的导航网格Tile Bounds。您可以通过选择“WorldOutliner”–>“RecastNavMesh-Default”–>启用“Draw Tile Bounds”来可视化Tile Bounds。


3 实时生成导航模型

Generation Mode描述
Static导航网格离线生成,并与关卡一起保存。 在运行时加载,无法更改。
Dynamic离线生成并与关卡一起保存或在运行时构建。 在运行时,可以实时更新并生成导航相关数据。
Dynamic Modifiers Only导航网格是离线生成的,并与关卡一起保存。 在运行时,只有 Navigation Modifiers(如 Navigation Areas、Navigation Links 和动态对象)可以通过更改成本或块区域来修改现有 Navigation Mesh。 运行时不会生成新的导航网格表面。
这种方法允许导航网格缓存碰撞数据,并且可以使受影响图块的处理成本降低 50%。
高级用户应在仔细考虑其优点和限制后使用此模式。

Dynamic Modifiers Only

设置实时生成方式。项目设置–>NavigationMesh–>Runtime Generation。
在这里插入图片描述
只有当Actor拥有NavModifier组件时有效。
在这里插入图片描述

注意关卡中没有生成新的导航网格(正在生成的图块显示为红色)。 导航修改器只是更改现有的导航网格。

示例中,目前同时加RotatingMovement组件有效,单加NavModifier无效,原因未知。


Dynamic

设置实时生成方式。项目设置–>NavigationMesh–>Runtime Generation。
在这里插入图片描述
在这里插入图片描述

Note: 强制生成具有高计算成本的导航网格。


三、自定义导航区域和查询筛选器

1. 自定义区域类(Nav Area)

NavModifierVolume拖动到关卡中。创建蓝图继承NavArea,命名为BP_Area_Neutral。打开BP_Area_Neutral,修改默认成本乘数和固定区域输入成本。选择颜色,编译并保存。
将创建好的NavArea添加到NavModifierVolume中的AreaClass里。
在这里插入图片描述


2. 创建导航查询筛选器(Navigation Query Filter)

创建蓝图继承NavigationQueryFilter,命名为BP_QueryFilter1。打开BP_QueryFilter1,添加并修改Areas数组,加入上一步创建的AreaClass,重写通过成本,
在这里插入图片描述

由于BP_QueryFilter1 BP_Area_Lane2是最便宜的路线,因此Agent使用它来到达球体。
在这里插入图片描述

四、在导航系统中使用回避

方法描述局限性
Reciprocal Velocity Obstacles (RVO)
相互速度障碍
- 代理通过在指定半径内使用速度矢量来避开障碍物。
-包含在角色类的角色移动组件中。
- 与绕行人群管理器相比,配置较少。
- 仅限于角色类。
- 不使用导航网格进行回避,因此代理可能会“越界”。
Detour Crowd Manager
人群绕行
- 代理通过使用路径优化以及指定半径内的速度矢量来避开障碍物。
- 包含在绕道拥挤的AI控制器类中
具有在项目设置中定义的固定最大代理数。

1. 使用RVO避免(Reciprocal Velocity Obstacles)

打开角色蓝图,选择Character Movement Component,导航到“角色移动:回避”部分,启用“UseRVOAvoidance”复选框,并将“回避考虑半径”设置为 100。
在这里插入图片描述
效果如下
在这里插入图片描述


2. 使用人群绕行避免(Detour Crowd Manager)

打开角色蓝图,将AIController替换为Detour Crowd AI Controller,运行即可。
也可以调整绕行人群管理器系统的多个设置,例如系统使用的最大代理数和用于避免计算的最大代理半径。
在这里插入图片描述

五、使用Navigation Invokers

概述

  • 这是一种仅围绕特定目标本地构建导航的方法。
    在Actor上添加Navigation Invoker组件,用于在运行时围绕代理生成导航网格。此方法不再需要在编辑器中构建导航网格,还可以限制在运行时生成的切片数。

非常适合在编辑器中构建导航网格不切实际的大型关卡


设置

  1. 向关卡中拖入导航网格。
  2. 项目设置–>NavigationSystem—>启用 Generate Navigation Only Around Navigation Invokers
  3. 项目设置–>NavigationMesh—>Runtime Generation—>Dynamic。
    在这里插入图片描述
    4.添加组件Navigation Invoker。打开细节面板,根据需求更改切片生成半径(用于生成导航网格切片的参与者周围的半径)和切片删除半径(用于删除导航网格切片的参与者的半径)。
    在这里插入图片描述
    效果如下:
    在这里插入图片描述

六、优化导航网格生成速度

Note: 最新版本可在引擎中找到。目录如下:Engine\Source\Runtime\NavigationSystem\DevDocs\How To Optimize Navmesh Generation.md

导航系统提供了各种设置,高级用户可以使用这些设置来修改关卡中导航的计算方式。


1. 建议

1.1 尽可能使用最高Cell Size和Cell Height

Cell SizeCell Height定义了用于生成导航切片的体素大小(Cells)。体素越小,获得的精度就越高,障碍物周围的导航就越准确。但是,体素越小,在运行时重新构建导航网格时需要的处理就越多。

Cell Size=19
在这里插入图片描述

Cell Size=64在这里插入图片描述

因此,在Agent所需的精度下,CellSize尽可能调大。


1.2 限制Tile Size

导航网格分为多个tiles,由于每个tiles都是从cells构建的,因此重新构建导航tiles将导致使用新的碰撞信息重新创建其所有cells。
较大的tiles包含更多的cells,重建成本高于较小的tiles。但是,在处理tiles时,系统还会处理其边缘上的连续cells。在设置切片大小时,应考虑此开销成本,因为在某些情况下,处理许多较小tiles的开销成本可能大于重建单个大型tiles的成本。

建议:tiles大小应设置为每侧 32128 个cells之间。这将在运行时重建tiles时提供最佳性能。
即Cell Size=64时,TileSizeUU>2048 (6432),且TileSizeUU<8192 (64128)。
在这里插入图片描述


1.3 对网格使用简化碰撞

导航系统使用每个对象的碰撞数据来生成导航网格。
因此, 碰撞网格中使用的三角形计数越低,生成速度就越快。

1.4 减少影响导航网格的对象数

默认情况下,关卡中的蓝图Actor和静态网格体会影响导航。影响导航tiles的对象数对生成该tiles的成本有直接影响。
因此, 选择任何不应影响导航网格的Actor,在细节面板中,禁用Can Ever Affect Navigation
如果可能,应避免同时影响大型tiles区域或多个tiles。

2. 用于管理导航生成的有用开发人员工具

在战略时期锁定和解锁导航网格生成
可以手动控制在所有资源完成加载后解锁导航网格生成。此方法可防止导航系统多次重建同一tiles。

  • 锁定导航网格生成,设置bInitialBuildingLocked=true;
  • 解锁生成,调用ReleaseInitialBuildingLock()。解锁后,导航网格将重建所有被加载的资源标记为脏的tiles。
  • 为了防止这种情况,可以在解锁之前,调用DefaultDirtyAreasController.Reset()。

启用多线程导航网格生成
您可以通过在"项目设置"–>NavigationSystem中的MaxSimultaneousTileGenerationJobsCount来控制多线程导航网格的生成。请注意,这受到 FRecastNavMeshGenerator::Init()中工作线程总数的限制。

将动态障碍物与全动态导航网格生成结合使用
您可以将关卡中的Actor标记为动态障碍物,Actor需要有Collision组件。动态障碍物标记需要重建生成的导航网格表面。这可以防止重新生成整个导航tiles。

使用此方法比生成完整的导航tiles成本更低,当移动障碍物顶部不需要导航网格表面时,应使用此方法。
在这里插入图片描述

用法猜测,当Actor顶部有导航网格,却不想用时,添加Collision组件,将AreaClass改成NavArea_Null,再启用DynamicObstacle。这样Actor顶部的导航网格就去掉了。


将数据块流用于在子关卡中加载的静态导航网格体
如果对导航网格体的唯一更改来自加载和卸载子关卡,则可以将导航网格体生成方法设置为静态并使用 NavMesh 数据块流式处理,而不是使用动态导航网格体。

使用此方法,导航网格将在编辑器中完全构建,并且只有相关部分将在运行时loaded in and out。

七、世界分区静态导航网格体

世界分区静态导航网格体(官方链接)

  • 11
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值