当前位置: 首页 > news >正文

UE NavigationSystem的相关实现

导航数据的构建流程

导航数据的收集

导航系统中绑定了Actor、Component注册完成以及取消时的委托,通过这些委托把数据及时更新到导航系统的八叉树结构中

导航系统的辅助结构DefaultOctreeController、DefaultDirtyAreasController分别承担了空间数据查询和置脏区域重新构建的任务,后者会把置脏数据最终投递到导航数据生成器的待处理结构里最终执行生成操作

开启构建操作(静态构建)

开启导航数据构建有几种情况:开启了动态导航、指令集开启、编辑器模式下的自动构建开启、调整导航偏移导航失效造成的重新构建。构建执行流程大致如下:

  1. 当开启导航构建后导航系统首先重置掉待处理区域变更请求以及控制置脏数据的管理器,然后迭代所有的ARecastNavMesh执行同名构建函数RebuildAll

  1. ARecastNavMesh首先会检查是否有正在构建操作如果存在操作则取消并重置,构建新的导航数据生成器实例并执行初始化,在初始化中进行有效区域边界更新并置脏所有的边界

  1. 把边界数据投递到待处理结构中,然后通过执行构建生成器的EnsureBuildCompletion函数确认所有的构建工作完成,实质上是把所有的待处理结构打包成异步或者同步执行的任务来处理

  1. 其中值得提及的是收集碰撞数据的方法:导航系统的辅助结构DefaultOctreeController中的NavOctree与DirtyBound做交叉检测,符合的则做数据收集

  1. 使用瓦片生成器结构构建瓦片数据

  1. 瓦片导航数据生成完成以后会把生成的数据添加到ARecastNavMesh数据真正的持有者DetourNavMesh(dtNavMesh)中

  1. 动态导航数据与静态生成区别:动态导航模式下导航系统中挂载的Actor、Component注册取消委托受场景变更的影响会不断的更新,进而推动整个构建导航逻辑的执行(而且在动态模式下这些具有碰撞数据的实例会及时导出碰撞数据)。

生成瓦片数据的逻辑

当FRecastTileGeneratorTask异步执行或者同步执行一个构建的任务时FRecastTileGenerator::DoWork的调用就开始了,FRecastTileGenerator结构封装了生成单个瓦片的功能逻辑(封装Recast导航数据生成流程),DoWork的执行流程如下:

  1. 完成几何模型碰撞数据收集和缓存,其中包括顶点数据、索引数据、可行走斜坡结构数据、修改器、导航连接、瓦片原生几何数据等

  1. 构建高度场域数据(rcHeightfield)

  1. 计算光栅化遮罩(对导航Modifier进行处理)

  1. 光栅化或者说体素化三角形面(其中包括几何Transform数据从UE坐标到Recast的坐标转换)

  1. 标记可行走区域

  1. 体素边界过滤,防止边界外生成体素数据,通过InclusionBounds边界框判定(ApplyVoxelFilter)

  1. Recast的生成过滤(WalkableClimb、walkableHeight)

  1. 生成紧缩高度场域(CompactHeightField)

  1. 根据walkableRadius剔除边缘(rcErodeWalkableAndLowAreas)

  1. 根据选择的算法生成区域数据(rcBuildDistanceField)

  1. 生成导航数据保存到瓦片生成器中

  1. 回收脚手架结构内存

导航数据的查询

导航系统封装的查询接口

  • K2_ProjectPointToNavigation 根据传入的点获取在NavMesh上的投影位置

  • K2_GetRandomReachablePointInRadius 获取指定半径内随机的一个导航可达点位

  • K2_GetRandomLocationInNavigableRadius 在给定的原点半径内的导航空间中生成一个随机位置

  • GetPathCost 获取路径消耗,不推荐使用

  • GetPathLength 获取路径长度, 不推荐使用

  • FindPathToLocationSynchronously 同步地获取两点间的导航路径

  • FindPathToActorSynchronously 同步地获取到达指定Actor的导航路径

以K2_GetRandomReachablePointInRadius为例说明导航数据查询路径

  1. 调用核心ARecastNavMesh的GetRandomPointInNavigableRadius函数

  1. ARecastNavMesh很多时候是空壳逻辑它会把逻辑转交给FPImplRecastNavMesh

  1. FPImplRecastNavMesh结构的ProjectPointToNavMesh函数会构建出一个dtNavMeshQuery查询结构来完成Ploy2D的相关查询

导航系统的配置参数说明

属性名字

属性描述

DefaultAgentName

默认的导航代理名字,用于适配、查找默认的导航配置、导航数据,为空的情况下默认会把代理配置中的第一项作为默认配置

CrowdManagerClass

定义导航系统使用的自定义CrowdManager基类,目前不需要修改

bAutoCreateNavigationData

是否自动创建导航数据,通常情况下会在地图加载完成时、导航体积发生变更执行操作

bSpawnNavDataInNavBoundsLevel

是否允许在子关卡中生成导航数据,否则在持久关卡中创建

bAllowClientSideNavigation

是否允许客户端开启导航,默认客户端导航模式是关闭的,关闭的情况下整个导航系统不会创建

bShouldDiscardSubLevelNavData

是否要丢弃子关卡中的导航数据,该操作在地图加载完成后通过委托回调进行检测完成。如果是勾选状态则整个子关卡中的RecastNavMesh会被销毁占用的内存会被释放

bTickWhilePaused

当世界关卡处于Paused状态时是否要停止导航系统的Tick

bInitialBuildingLocked

在导航系统初始化完成或者导航系统重新加载完成的时候是否锁定导航系统的构建,如果为true只有在释放锁定标记后才能进行导航数据构建

bSkipAgentHeightCheckWhenPickingNavData

在通过NavConfigProps进行导航数据匹配时,是否忽略对代理高度的检查

DataGatheringMode

影响导航数据收集,注释说设置在构建碰撞信息时应如何收集导航数据。它的实质是在世界场景下Actor中的组件注册完成后导航系统中的OnComponentRegistered会被调用进而执行RegisterComponentToNavOctree,最终会执行到AddElementToNavOctree该函数会调用FNavigationOctree::AddNode函数,这个函数是最终的调用,它会执行ComponentExportDelegate委托的绑定,而其中绑定的是几何导出的逻辑处理FRecastNavMeshGenerator::ExportComponentGeometry

GeometryExportVertexCountWarningThreshold

当正在执行导出的数据结构中,定点数据容量大于此值时会产生日记记录,可参见ValidateGeometryExport

DirtyAreaWarningSizeThreshold

当该值为正值,向置脏控制器中添加的置脏区域(2D)大于该值时,产生警告日志

GatheringNavModifiersTimeLimitWarning

如果 GatheringNavModifiersWarningLimitTime 为正数,如果调用 GetNavigationData 所花费的时间超过 GatheringNavModifiersWarningLimitTime,它将打印警告

bGenerateNavigationOnlyAroundNavigationInvokers

是否仅在指定的目标对象周围生成导航数据,一旦开启全图可导航,依赖于导航动态生成,依赖于NavigationInvokerComponent

ActiveTilesUpdateInterval

激活的Tiles更新间隔依赖于bGenerateNavigationOnlyAroundNavigationInvokers

SupportedAgents

支持的代理导航配置

SupportedAgentsMask

导航系统对支持的代理控制

导航数据查询规则

通过导航配置FNavAgentProperties结构查询导航数据实例时会发现该结构的IsEquivalent函数起着至关重要的作用,而该函数中起决定因素的值是AgentRadius、AgentHeight,当这两个参数各自的差值小于默认精度5.f则认为这两个导航代理配置是等价的,因此有以下匹配规则:

  1. AgentToNavDataMap中通过FNavAgentProperties类型的Key查询到指定的NavData返回

  1. 如果无法查询到最佳匹配项则按照最优匹配原则获取指定导航数据配置查询AgentToNavDataMap返回

所有NavData实例都会在AgentToNavDataMap、NavDataSet中注册

WP情况下对导航的影响

WP下多了对区域导航数据的流入流出支持,它的核心实质是根据导航数据构建支持流入的Actor实例ANavigationDataChunkActor,该实例中保存了生成的导航数据URecastNavMeshDataChunk(TArray Tiles)。当该Actor实例被装载时携带的导航数据会替换掉DetourNavMesh中的Tile数据,卸载的时候又从DetourNavMesh移除。

Navigation Mesh参数说明

属性名字

属性描述

CellSize

水平方向上体素尺寸tiles大小应设置为每侧32到128个cells之间。这将在运行时重建tiles时提供最佳性能

CellHeight

垂直方向上体素尺寸

AgentRadius

代理半径

AgentHeight

代理高度

AgentMaxSlope

代理可以移动的最大斜率(角度)

AgentMaxStepHeight

Agent的可攀爬高度

MinRegionArea

允许形成孤岛区域的最小单元数

MergeRegionSize

分水岭算法中跨度计数小于此值的任何区域都将与更大的区域合并

MaxSimplificationError

细节网格表面偏离高度场的最大距离

TileSizeUU

单个tile的大小

TilePoolSize

NavMesh可以容纳的最大图块数

bFixedTilePoolSize

如果为真,NavMesh将为Tile分配固定大小的容量,开启以支持流式传输

MaxSimultaneousTileGenerationJobsCount

设置一次运行的异步瓦片生成器的数量限制,也用于一些同步任务

TileNumberHardLimit

导航网格图块数量的绝对硬性限制。在使用带有navmesh的大地图进行修改时要非常非常小心。一个空的tile需要176个字节,并且空的tile是预先分配的

DefaultMaxSearchNodes

指定执行导航查询时使用的A*节点的默认上限限制

DefaultMaxHierarchicalSearchNodes

指定执行分层导航查询时使用的A*节点的默认上限限制

RegionChunkSplits

用于区域分区的块分割数(沿单轴),仅用于ChunkyMonotone算法

LayerChunkSplits

用于区域分区的层分割数(沿单轴),仅用于ChunkyMonotone算法

bSortNavigationAreasByCost

控制导航区域在导航网格生成期间应用到导航网格之前是否按成本排序。 当区域重叠时,这是相关的,我们也希望区域成本表达区域相关性。 将其设置为 true 将导致区域按成本排序,但它也会增加导航网格生成成本一点

bIsWorldPartitioned

是否是world partitioned map

bPerformVoxelFiltering

是否执行体素过滤

bMarkLowHeightAreas

标记上方自由高度不足的区域,而不是将其切掉(仅适用于使用替换模式的区域修改器)

bUseExtraTopCellWhenMarkingAreas

应用于导航网格时,将区域导航修改器的边界顶部扩展一个单元格高度

bFilterLowSpanSequences

如果跨度上方的间隙小于指定高度,则将可步行跨度标记为不可步行。

bFilterLowSpanFromTileCache

如果设置,只有具有相应区域修改器的低高度跨度将存储在图块缓存中(减少内存,如果没有完整的图块重建就无法修改)

bDoFullyAsyncNavDataGathering

navmesh 数据收集永远不会发生在游戏线程上,只会在后台线程上完成

导航数据的内存占用

NavOctree memory :导航八叉树的空间占用

ARecastNavMesh memory : DetourNavMesh中的所有瓦片结构内存总和 + 激活路径分配的内存(ActivePaths)+ 支持的区域结构分配的内存(SupportedAreas)+ 查询过滤器分配的内存(QueryFilters)+ 区域映射Map分配的内存(AreaClassToIdMap)+ 导航生成器内存占用(待处理任务数据结构大小 + 生成器结构本身大小 + 运行时任务结构大小 + 瓦片构建器分配的内存总和)

导航数据生成相关验证

多代理下的导航数据验证

支持的代理越多产生的数据容量越大,而且不同的代理配置生成的数据容量也是不同的

相关文章:

UE NavigationSystem的相关实现

导航数据的构建流程导航数据的收集导航系统中绑定了Actor、Component注册完成以及取消时的委托,通过这些委托把数据及时更新到导航系统的八叉树结构中导航系统的辅助结构DefaultOctreeController、DefaultDirtyAreasController分别承担了空间数据查询和置脏区域重新…...

Java 继承

文章目录1. 继承概述2. 变量的访问特点3. super 关键字4. 构造方法的访问特点5. 成员方法的访问特点6. 方法重写7. 继承案例1. 继承概述 继承是面向对象三大特征之一。可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。 publ…...

Python学习笔记8:异常

异常 一些内置的异常类 类名描述Exception几乎所有的异常类都是从它派生而来的AttributeError引用属性或给它赋值失败时引发OSError操作系统不能执行指定的任务(如打开文件)时引发,有多个子类IndexError使用序列中不存在的索引时引发&#…...

python保留小数函数总结

python保留小数——‘%f’‘%.nf’% x(定义的变量) 例子:a 82.16332 print(%.1f% a) print(%.2f% a) print(%.3f% a) print(%.4f% a) print(%.10f% a)输出结果python保留小数——format()函数Python2.6 开始&#xff…...

狐狸优化算法(Matlab代码实现)

👨‍🎓个人主页:研学社的博客💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密…...

浏览器自动化框架沦为攻击者的工具

5月27日消息,安全公司Team Cymru的研究人员表示,越来越多的威胁参与者正在使用免费的浏览器自动化框架作为其攻击活动的一部分。 研究人员表示,该框架的技术准入门槛故意保持在较低水平,以创建一个由内容开发者和贡献者组成的活跃…...

SQL必备知识(自用)

数据库基础知识sql和mysql的区别:数据库查询大全(select)1、select 字段名 from 表;2、In查询:用于过滤你所需要查询的内容3、范围查询:between4、模糊查询:like5、查询空值/非空:is…...

BI工具术语表大全:从字母A-Z全面收录

谈到商业智能行业,变革是不可避免的。为了跟上步伐,各种各样的BI 解决方案正在快速迭代更新,以满足企业的数字化需求,那么市场上BI 工具种类繁杂,到底如何选择适合功能全面、满足自己企业运转情况的、合适的BI 工具呢&…...

vue3 + vite + ts 集成mars3d

vue3 vite ts 集成mars3d 文章目录vue3 vite ts 集成mars3d前言一、创建一个vue3 vite ts项目二、引入mars3d相关依赖三、vite.config.ts 相关配置四、 新建DIV容器 创建地图前言 使用mars3d过程中,需要集成mars3d到自己的项目中,mars3d开发教程…...

跨境卖家必看的沃尔玛Walmart商家入驻教程

沃尔玛Walmart作为作为全球连锁超市的鼻祖,有不可比拟的知名度。当沃尔玛从线下延伸到线上后,就成为一个自带IP与流量的线上平台,在全世界都拥有数量庞大的消费者群体。所以龙哥就结合自己注册Walmart的过程给大家详细讲解一下。 Walmart卖家…...

【GANs】什么是饱和损失函数 Non-Saturating LossFunction

Saturating VS Non-Saturating Loss functions in GANs【GANs】什么是饱和损失函数 Non-Saturating LossFunctionSaturating VS Non-Saturating Loss functions in GANs 饱和Loss 普通GAN loss是生成器希望最小化被判断为假的概率。x取值范围是[0,1],所以图中函数…...

USB接口虚拟网卡

1 基本概念 1.1 USB转以太网 - ASIX 4-byte length header before every ethernet packet. - Microchip LAN7800 128x32 bit Descriptor RAM, 32 bits DP_DATA address offset 030h for Descriptor RAM access. - Windows CMD参数格式: route /? -> Linux -h …...

基于SpringBoot的外卖项目的优化

基于SpringBoot的外卖项目的优化1、缓存优化1.1、缓存短信验证码问题分析代码改造1.2、缓存菜品数据实现思路1.3、Spring Cache介绍常用注解CachePutCacheEvictCacheable使用方式1.4、缓存套餐数据实现思路代码改造2、读写分离2.1、主从复制存在的问题介绍配置配置主库--master…...

Ubuntu20.04/22.04 ESP32 命令行开发环境配置

ESP32 芯片系列 ESP32分三个系列 ESP32-S ESP32-S3: Xtensa 32位 LX7 双核 240 MHz, 384KB ROM, 512KB SRAM, QFN7x7, 56-pin, 2.4G Wi-Fi BTESP32-S2: Xtensa 32位 LX7 单核 240 MHz, 128KB ROM, 320KB SRAM, QFN7x7, 56-pin, 2.4G Wi-Fi ESP32-C ESP32-C3: RISC-V 32位 单…...

Kali Linux使用Metasploit生成木马入侵安卓系统

额,这是我最后一篇文章了,周一我们开学了 文章目录前言一、Metasploit是什么?演示环境二、生成可执行木马文件1.生成2.运行命令并生成木马配置参数入侵安卓手机命令1.查看对方手机系统信息查看对方手机安装哪些app文件总结前言 前言&#xf…...

数据库复习1

一. 简答题(共1题,100分) 1. (简答题) 存在数据库test,数据库中有如下表: 1.学生表 Student(Sno,Sname,Sage,Ssex) --Sno 学号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 主键Sno 2.教师表 Teacher(Tno,Tname) --T…...

18. linux系统基础

shell 命令解析器 命令解析器作用: 他把在终端上输出的命令 给你解析成内核可以识别的指令,内核 是经过命令解析器的加工 shell在找命令的时候,所包含的路径,就是在这些路径里去 找 找到就执行 找不到就报错 报错 要么 这个命…...

ssh远程登录报错:kex_exchange_identification: Connection closed by remote host

基本信息系统:MacOS Catalina 10.15.7报错信息:终端登录远程服务器时报错:kex_exchange_identification: Connection closed by remote host复制然而服务商的一键登录或VNC登录正常。解决方案首先使用以下命令debug登录过程,以便定…...

Quartus II 的入门级使用

好久没有用VHDL写东西了,今天需要完成一个项目,重新复习一下新建工程新建工程file-->New Project Wizard, next, 选择存放的路径名字(projecttop-level 名字要相同),next,File name名字同上,…...

Java EE|TCP/IP协议栈之TCP协议工作机制上

文章目录前言一、确认应答二、超时重传三、连接管理三次握手四次挥手前言 前边,我们已经大概交代了TCP的报文结构。但是仍有一些字段我们不确定到底怎么理解,这里就分析TCP的内部工作机制了。 TCP的内部很复杂,有很多机制,这里我们…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...