最新版本已支持 UE5,详见 github 的 UE5.0 分支:ue4-export-nav-data/tree/UE5.0。
Recast Navigation是一个开源的游戏导航 / 寻路引擎,可以为游戏中的 AI 提供寻路计算。UE 和 Unity 都是集成了 RecastNavigation 来为游戏提供导航和寻路计算 (当然是修改过的版本),UE 的模块NavigationSystem
以及 NavMesh
中可以看到相关的代码实现。
最近有个需求是要将客户端的地图信息导出给非 UE 网络架构的服务端,用于在服务器上对玩家位置的校验,想到可以把客户端的生成的导航数据导出作为客户端世界的 地图 ,所以折腾了一下写了一个 UE 的插件(开源在 Github 上:**ue4-export-nav-data)实现了 直接 ** 将 UE 生成的导航数据导出,有兴趣的可以直接去看具体的代码。
根据导出的导航数据可以完整地在非 UE 网络架构的服务端上实现基于 Recast Navigation 的寻路计算,而且与 UE 无缝衔接。
**2019.12.04 Update:** 本插件已上架虚幻商城,购买链接ExportNavigation,为了程序员情怀支持开源,所以该项目在 Github 上的开源仓库不会关闭,但基本不会更新,如果该插件对你有用,欢迎在商城购买支持作者。
Recast Navigation
首先,先来简单介绍一下编译 Recast 的 github 开源版本,UE 引擎中使用的 recast 就是基于该开源版本修改的,截止到 UE_4.22.3
,UE 使用的 recast 版本为v1.4
(可以从Source/Runtime/Navmesh/Recast-Readme.txt
中查看不同引擎版本使用的 recast 版本信息)。
RecastNavigation 在 Github 上的源码地址:recastnavigation.
recastnavigation的代码中提供了导航网格生成与计算寻路的工具RecastDemo
,可以作为在项目中集成 RecastNavigation 的案例。
README.md
里面写了各个平台的编译流程,我在这里详细展开一下 Windows 下编译流程。
- 首先下载premake5,并将其添加到系统 PATH 路径
- clone RecastNavigation 的代码
- 下载 SDL2(选择 Development Libraries),并将其解压到
recastnavigation\RecastDemo\Contrib
目录下,将文件夹改名为SDL
,目录结构为:
1 | D:\recastnavigation\RecastDemo\Contrib\SDL>tree /a |
在
recastnavigation\RecastDemo
目录下执行命令premake5 vs2017
(vs201x 取决于你当前系统中安装的版本),它会在RecastDemo
目录下创建build/vs2017
目录,里面是 VS 项目的解决方案。
打开
RecastDemo\Build\vs2017\recastnavigation.sln
,编译即可。编译出来
RecastDemo.exe
位置在RecastDemo\Bin
。
1 | C:\Users\imzlp\source\repos\recastnavigation\RecastDemo\Bin>tree /a /f |
其中关键的几个文件:DroidSans.ttf
/RecastDemo.exe
/SDL2.dll
/Meshs/
。
注意:必须把 obj 文件放到
Meshs/
目录下才可以被RecastDemo
识别。
之后就可以打开 RecastDemo.exe
在默认提供的三个 obj
的模型上进行导航数据生成的测试了,通过 Build
生成,然后 Save 保存会在 RecastDemo.exe
所在的目录产生一个 .bin
文件,即使用 recast 生成的导航数据。
注意 :从 UE 导出 Navmesh 的含义是,把 UE 寻路范围内的模型导出,再通过RecastDemo
在该模型的基础上生成寻路数据。这也导致了在 UE 中添加影响寻路的框,导出 Navmesh 在 RecastDemo
生成时无法生效。
Plugin: ue-export-nav-data
该插件是从 UE 中导出 RecastNavigation 的工具,分为两个模块:ExportNavRuntime
与 ExportNavEditor
,编辑器模块提供了 UE 中编辑器ToolBar
的按钮,在编辑器中导出导航数据。
点击之后选择路径,会在选择的路径下生成两个文件:.bin
与obj
,在 Windows 下会自动在资源管理器中打开导出目录。
- bin:UE 构建完成的导航数据,给外部服务器使用。
- obj:UE 中放置寻路的 Mesh,可以从 RecastDemo 中生成 bin 文件。
另外,我提供了 NavData
可以在运行时导出,但是 NavMesh
不支持,因为 UE 的导航是预计算的,具体可以看 UFlibExportNavData
中提供的方法。
我在 C++ 和蓝图中也提供了从导出的 bin 中验证位置是否是合法的寻路位置的两种方法:
1 | bool UFlibExportNavData::IsValidNavigationPointInNavbin(const FString& InNavBinPath, const FVector& Point, const FVector InExtern = FVector::ZeroVector); |
可以与 UE 中提供的 UNavigationSystemV1::ProjectPointToNavigation
来对比验证导出数据是否匹配。
还有一个传入起始点来获取导航路径点的方法:
1 | bool FindDetourPathByNavMesh(dtNavMesh* InNavMesh ,const FVector3& InStart, const FVector3& InEnd, std::vector<FVector3>& OutPaths); |
可以与引擎中 UNavigationSystemV1::FindPathToLocationSynchrously
的结果一致,传入游戏中的世界坐标,函数内部有转换,返回的也是世界坐标。
该插件其优点为:
- 并非先从 UE 导出 NavMesh 的
.obj
再使用RecastDemo
生成,而是直接从 UE 导出bin
,当然我也保留了导出 NavMesh 为obj
; - 因为是直接从 UE 生成之后的导航数据导出,所以是所见即所得,解决导出 NavMesh 再 RecastDemo 生成导航网格时无法避免某些区域不生成寻路,以及避免 UE 与 RecastDemo 各种寻路参数的不一致产生的寻路数据不一致;
- 额外抽取出 ue 的 ue-detour 版本,可以无缝集成到外部服务器中,客户端坐标与服务端坐标无需转换(当然 UE 的坐标与 Recast 的坐标需要转换,但是内部已经处理,使用时不需要手动转换)。
UE 的坐标系与 Recast 的坐标系之间的转换可以使用 UE4RecastHelper
的两个函数:
1 | namespace UE4RecastHelper |
Library: ue-recast-detour
这个是我从 UE 代码中抽取出的 recast detour 库,在 UE 源码的路径下为Runtime/Navmesh/Detour
,主要目的是保证 UE 客户端与外部服务器的验证方法一致。
因为在 github 上的 RecastNavigation 要高于 UE 使用的版本,而且前面提到 UE 在 recast 的基础上做了不少改动,为了防止代码的差异造成的不同结果,我将 ue 使用 (以及魔改) 过的版本抽出来供外部使用,这样可以确保客户端和服务端的结果是一致的。
代码放在了 github:ue4-recast-detour,该仓库的 Detour/
目录下为 Detour 的库的全部代码。
其余的代码是我实现的与 UE 进行验证和 UE 与 Recast 坐标转换的库 UE4RecastHelper
类以及实现的一个简单的命令行程序,用来测试 UE 中的世界位置是否在 bin 中的寻路数据中合法。
UE4RecastHelper
目前 (2019.11.01) 提供了 dtNavMesh
与bin
文件之间 serialize
/deserialize
的方法;以及与 UE 中函数 UNavigationSystemV1::ProjectPointToNavigation
实现方法相同的函数UE4RecastHelper::dtIsValidNavigationPoint
,用来验证点是否是合法的寻路点,保证了 UE 客户端与外部服务器的验证方法一致。
Detour
所支持的操作都可以在服务器上实现(因为已经从 UE 里拿到了导航数据),可以根据需求扩展。
再简单说一下 ue-detour.exe
这个工具怎么用,直接在命令行启动 ue4-detour.exe
会提示用法。
首先,要先从 UE 中将导航数据导出,这里需要用到的只有 .bin
文件,如生成在 D:\NavData
。
然后找到 ue4-detour.exe
就可以使用下列命令了:
1 | D:\>ue4-detour.exe |
在蓝图中也可以直接加载 .bin
进行测试:
End
本篇文章用到的开源仓库:
Update
2021.05.27 Update:
- 插件支持 UE5,支持导出 UE5 的 NavMesh 数据及导航网格
- 数据与 ue-detour 验证成功