精通 C++游戏动画编程(OpenGL 和 Vulkan 的高级游戏动画技术) - 13 添加简单导航

在上一章中,我们创建了一个独立的八叉树来增强碰撞检测,使我们能够以快速且计算成本低的方式检测实例与场景几何体之间的碰撞。 然后我们在应用中添加了简单的重力系统,使实例能保持在地图地面上,最终实现了实例在场景地板和小山坡上行走的效果。 最后,我们对实例的脚部应用了反向动力学,使其在攀登山坡或地图斜坡区域时能保持双脚着地。

本章我们将实现路径寻找与导航功能。 首先简要概述电脑游戏中常用的导航方法,接着探索并实现 A*寻路算法。 然后我们会在应用中添加导航目标点,提供在虚拟世界中设置路径终点的简易方式。 本章最后将实现朝向路点的导航功能,使实例能够行走或跑向指定目标。

在本章中,我们将涵盖以下主题:

  • 不同导航方式概述
  • A*寻路算法
  • 在地图中添加导航目标点
  • 导航至目标实例

导航方式概览

寻路与导航在电子游戏中的应用历史远比人们想象的更为悠久。 让我们来探讨几种导航方法。

基于距离的导航

最早使用简单算法模拟敌人智能行为的游戏之一,是南梦宫开发的 《吃豆人》。 游戏中四个幽灵角色(Blinky、Pinky、Inky 和 Clyde)各自具有略微不同的"性格",这仅通过它们移动时的目标点来实现。

当红色幽灵(Blinky) 直接追逐吃豆人时,粉色幽灵(Pinky)和蓝色幽灵(Inky)会试图绕到吃豆人前方,实际上形成对玩家的包围之势。 第四只橙色幽灵(Clyde)则"随心所欲",会在追击玩家和逃跑之间切换。

关于新路径的选择决策仅在迷宫交叉口处进行,完全基于该交叉口所有可能路径到目标方块的直线距离。 游戏并未采用更高级的前瞻路径规划,这有时会导致决策失误。 图 13.1 展示了交叉口处的这种决策场景:

 

图13.1:吃豆人游戏中红色幽灵的导航决策

图 13.1 中,绿色方框是触发左右移动决策的判定区域,两条绿色虚线表示到红色轮廓目标方格的直线距离。 尽管右侧路径更短,但由于左侧决策距离更近,幽灵会选择左侧路径,从而产生不规律的移动行为。 在附加资源章节中提供了深入了解幽灵导航内部机制的链接。

基于简单距离的导航至今仍应用于游戏中,例如根据敌我双方的速度和方向,计算敌人可能拦截玩家的位置。 随后会使用基于图的导航算法来规划前往玩家的路径。

基于图的导航

在图中,搜索算法使用图的节点来描述游戏地图上的位置 ,并用边来描述节点之间的连接关系。 通过构建地图的图结构,可以有条理地找到两个位置之间的最短路径。

导航中会用到多种图算法。 最常见的有:

  • 深度优先搜索 DFS
  • 广度优先搜索 BFS
  • 迪杰斯特拉算法
  • A*算法(读作“A 星”)

DFS 与 BFS 算法

这两种都是简单算法。DFS 采用"深度优先"方式遍历图,从起始节点访问到最远节点;而 BFS 则优先访问最近的节点,以"环形"方式逐步推进至下一层节点。 图 13.2 展示了一个由六个节点(A 至 F)组成的示例图:

 

图13.2:广度优先搜索与深度优先搜索

图 13.2 左侧的 BFS 算法从根节点(A)开始,首先访问最近的相邻节点(B、C 和 D),然后遍历至节点 E 和 F。 右侧的 DFS 算法则优先遍历子节点 D 及其子节点 F,接着访问节点 C 和 E,最后才到达节点 B。

迪杰斯特拉算法

迪杰斯特拉算法为图的边添加权重。 根据待解决问题的不同,这些权重可视为节点间移动的成本或距离。 该算法通过遍历整个图, 构建出从起始节点到图中所有其他节点的最短路径表。

图 13.3 展示了初始图及算法所有步骤执行后的结果:

 

图 13.3:一个图表及从节点 A 到所有其他节点的最短距离

通过使用迪杰斯特拉算法,可以遍历任何加权图,找到从一个节点到所有其他节点的最低成本(或距离)路径, 但必须为每个起始节点重新运行该算法。 关于该算法的完整描述, 附加资源部分提供了一个链接,展示了为图 13.3 中的图寻找最短距离的步骤。

A*算法

A*算法以 Dijkstra 算法为基础,但增加了两个改进:

  • 所谓的启发式函数被添加到每个节点,用于估算从该节点到目标节点的距离。
  • 该算法从起始节点搜索到指定的目标节点,通常在到达目标节点时终止。

通过结合从起始节点到当前节点的距离,以及从当前节点到目标节点的估算距离,并在遍历到下一个节点时使用最短总和,A*实现了向目标节点的定向搜索。 因此,与 BFS 或 DFS 进行无方向搜索不同,A*始终朝着目标节点的方向前进。 我们将在 A*路径查找算法章节深入讨论。

本节算法的一个缺点是,如果目标不是静态的,它们必须重新计算整个路径。 对于动态目标,像 LPA*、D*或 D*-Lite 这样的算法可能会提供更好的结果。 此外,自 A*算法问世以来,人们还开发了其他几种寻路算法,有的针对机器人等特殊环境,有的则像 Theta*那样进一步优化寻路过程的结果。

在探索 A*算法之前,我们先来看看电子游戏中另一种流行的导航类型——使用三角形或其他多边形来描述机器人和 NPC 的可行走区域,并简要了解一下作为创建导航数据替代方案的机器学习方法。

基于网格的导航

像《吃豆人》这样的简单游戏和许多策略游戏通过将世界划分为网格来实现基于距离的导航,通常由矩形或六边形结构构成。 但三维游戏(如开放世界)或第一人称、第三人称探索与战斗游戏的需求则有所不同。 由于虚拟世界的部分区域会重叠,需要采用三维结构才能引导计算机控制的角色在地图中穿行。

大多数使用三维地图的游戏都会采用导航网格、区域感知或两者结合的方式。

导航网格

导航网格 (也称为 NavMeshes)于 2000 年左右引入游戏领域。 导航网格是由多边形(大多数实现中使用三角形)构成的附加数据结构,覆盖在关卡几何体之上。 导航网格中的多边形标记了关卡的可行走区域,排除了计算机控制角色可能碰撞的所有物体和结构。

通过使用导航网格,当角色保持在导航网格上时,机器人或 NPC 可以在虚拟世界中行走,同时避免与静态关卡几何体进行昂贵的碰撞检测。 只有当角色可能离开导航网格时,才需要进行碰撞检测。 结合基于图论的算法(如 A*算法),可以实现对计算机控制角色行为的细粒度控制。 关于使用导航网格进行路径规划的全面介绍链接可在附加资源部分找到。 图 13.4 展示了一个简单示例:

 

图13.4:带有起点(绿色)、目标点(红色)及两者间路径的导航网格

图 13.4 中,上方图片展示了从起始三角形(绿色)到目标三角形(红色)的最短可能路径,该路径通过使用视线中的下一个顶点连接到网格的下一个尖角。

相比之下,中间图片中的路径将三角形中心作为寻路算法的图节点,而底部图片则使用三角形内部边作为图节点。

路径质量取决于网格结构以及三角形中哪些部分被用作图节点。 可以组合使用图 13.4 中的方法,因此三角形中心和边中点都可作为图节点。 生成的路径还可通过跳转到下一个直接可见节点及使用样条曲线进行平滑处理。

需注意,若边缘导航网格在狭窄通道中过于靠近墙壁或边界,实例可能会与墙壁发生碰撞,导致额外的移动修正或形成网格不可通行区域。 关卡中的静态障碍物也应保持安全距离绕行。

作为经验法则,使用实例的轴对齐包围盒边缘到中心的距离作为导航网格边缘与相邻关卡几何体之间的最小距离。 通过始终保持实例远离墙壁,在正常导航过程中就不会发生碰撞。

从关卡数据生成导航网格

通常,导航网格会手动创建并添加到关卡数据中。 但我们需要为互联网上的关卡提供解决方案, 因此将在代码中采用快捷方式,使用与检测实例是否与关卡地面碰撞相同的朝上三角形作为"可能可行走的地面"。

结合所有地面三角形之间的邻接关系,可以估算出关卡中的可行走区域。 关于地面区域创建代码的若干改进任务,可在实践环节部分找到。

通过使用导航网格,可实现两种导航方式:在虚拟世界中自由漫游,以及在路径点之间巡逻。

自由导航

自由导航模式下, 地图上的任意点都可作为起点或目标点。 从关卡的一个区域移动到另一个区域可能需要高昂的计算成本; 最坏情况下,寻路过程中需要检查整个网格。 此外,根据起点和目标点的精确位置,角色的路径在两次路径规划间可能完全不同。

航点导航

对于基于网格的导航, 更好的方法是在导航网格上定义彼此可见的路径点。 例如,一组房间中的每扇门都可以作为路径点,或者道路的每个分叉处。 当机器人在虚拟世界中移动时,到达目标路径点后会立即将下一个路径点设为新的目标。 如果玩家被发现后又丢失,机器人可以返回最近的路径点。 通过确保计算机控制的角色始终能"看到"至少一个路径点,规划到下一个路径点的路线就变得简单且计算成本低廉。

区域感知系统

1999 年,id Software 在 《雷神之锤 3 竞技场》 中使用了名为区域感知的系统。 不同于二维图表,该系统创建了关卡的简化三维模型,包含关卡结构、其他机器人和玩家的所有信息。

机器人不仅可以通过行走、跳跃或游泳穿越感知区域,还能借助传送器、弹跳板甚至火箭跳来实现移动。 凭借如此丰富的行动指令库,机器人可以轻松地在关卡中追踪玩家,或试图切断玩家的行进路线。

关于区域感知系统的完整说明可在其他资源部分的 PDF 文档链接中查阅。

利用机器学习生成导航数据

为计算机控制角色创建导航数据的一种较新方法是机器学习,主要采用所谓的强化学习形式 。在强化学习过程中,代表角色的智能体通过大量"试错"式回合自主探索虚拟世界,但会根据完成定义任务获得奖励或失败受到惩罚。

这类任务可能是"以最高生命值到达目标点"、"不从关卡坠落"或"以最短时间完成关卡"等。 通过考量先前探索获得的奖励与惩罚,智能体会优化其行为以实现奖励最大化与惩罚最小化。 当这些智能体生成的数据应用于游戏时,敌人角色就能运用机器学习得出的策略,使其在虚拟世界中的移动显得更加自然。

机器学习的两大挑战使得其使用既耗时又昂贵:

  • 目标、奖励和惩罚必须在计算过程中明确定义并适时调整。 即便我们人类认为目标和奖励已定义完善,机器学习算法仍可能找到意想不到的方式来最大化奖励。 初始设置的失误可能导致数据废弃,并需要整个机器学习周期完全重启。
  • 由于机器学习通过试错法探索虚拟世界,其进展具有不确定性,可能仅以微不足道的幅度推进。 即便是简单任务,也需要在游戏运行期间进行数千轮对局才能达成预期效果。 要创建能探索大型游戏场景的复杂 AI,可能需要消耗大量计算资源,从而导致过高的开发成本。

尽管机器学习可能产生比基于算法的导航更好的结果,但仍建议权衡可能的改进与额外成本之间的利弊。 在附加资源部分可查看展示机器如何学习驾驶汽车的进展视频链接。

在简要回顾了导航方法之后,接下来让我们深入探讨 A*算法。

A*路径寻找算法

A*算法于 1968 年计算机发展早期发表。 该算法源于一款名为 Shakey 的 AI 控制移动机器人的路径规划研究。 该机器人由斯坦福研究院开发, 其软件包含计算机视觉和自然语言处理功能,能够自主完成实验室内的简单任务(如行驶至指定位置),而无需预先描述每个具体动作。 更多关于该项目及机器人的详细信息,可参阅附加资源部分提供的链接。

但 A*算法与 Dijkstra 算法有何不同?<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

akluse

失业老程序员求打赏,求买包子钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值