热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[翻译]求生之路AI系统讲稿

之前在某网站上无意间看到关于求生之路(L4D)的AI系统讲稿ppt,所以特地去研究阅读了一下,看了第一遍后感觉也是懵懵懂懂的(英文真的令人头疼),算是大概了解了下流程,所以决定写一




之前在某网站上无意间看到关于求生之路(L4D)的AI系统讲稿ppt,所以特地去研究阅读了一下,看了第一遍后感觉也是懵懵懂懂的(英文真的令人头疼),算是大概了解了下流程,所以决定写一篇文章,好好记录一下具体讲了些啥。

当然由于本人知识存储或者英文翻译带来的理解不同可能会造成曲解,也请见谅!

讲稿可以从我的学习资料中找到。



一. 四个方面

具体讲解之前,先介绍一下求生之路这款游戏。

求生之路是Valve公司发行的一款第一人称设计游戏,使用的是起源引擎进行开发(半条命、CSGO等都是这款引擎)。求生之路中,剧情设定是在现代城市的恐怖氛围中,有成群的受感染的僵尸大军和恐怖的BOSS级变种人会持续来寻找攻击你,最多能组成四名"幸存者"一起同心协力杀出一条血路找到出口。



下面开始正题!

讲稿内容主要围绕着四个方面进行探讨,分别是:



  • Deliver Robust Behavior Performances (提供强大的行为表现力)

该章具体围绕僵尸AI的寻路路径规划、行为决策进行展开。



  • Provide Competent Human Player Proxies (提供有能力的电脑Bot代替人类玩家)

该章简单描述了一下电脑AI在幸存者阵营的决策处理。



  • Promote Replayability (促进重复可玩性)

该章介绍了一个"AI Director"的系统,通过该系统来产生一定随机性以及重复可玩性。



  • Generate Dramatic Game Pacing (产生引入注目的游戏节奏感)

该章具体讲述了如何把控游戏的整体节奏感,让每名幸存者都有不同的"情感强度"。


二. Deliver Robust Behavior Performances

首先讲到的是僵尸AI的移动路径规划。我们可以先看张图



对于环境中的移动,采用的是:



  • 在导航网格中使用A*算法

  • 创建层次不齐的路径选择

    这就引出了一个问题:如何让其移动时显得流畅


(1). 路径最优化



主要的思路就是:收缩路径上冗余的结点

同时带来了好处和坏处:



  • 好处: 创建了最小限度以及最直接的路径

  • 坏处: 在规划路径时对CPU性能消耗是不俗的

        在游戏中有些路径会经常被重新计算

        这样的跟随路径看上去很机械化


(2). 反应型跟随路径



主要思路就是:朝着“向前看”的方向走更远的路径

       采用局部躲避障碍



  • 好处: 路径重绘是节省的

        局部回避处理了一些小的物理道具、其他电脑bot以及角落等

        对于僵尸们的蜂拥而至有着完美配合

        结果产生的动作是易变的

  • 坏处: 可以避免过多路径的产生,但是需要重新绘制路径

看一下行径的过程

我们将路径最优情况和反应型跟随路径进行一下对比



(红线: 最优情况  蓝线: 反应型)

可以看到 反应型跟随路径产生的路径结果和最优情况的路径非常相接近

所以这就导致了在L4d中所有游戏角色都是采用反应型路径跟随


(3). 攀爬功能



  • 为了让游戏中常见的成群僵尸显得危险,他们有能力可以进行快速攀爬。

  • 攀爬是一种算法规则,使用相似的技术来局部躲避障碍

  • 攀爬算法主要解决两个问题:

    • 在游戏中错综复杂的几何路径导航

    • 借助可移动物理小道具来导航



以下是目标呈现图:


方法

电脑Bot会周期性地对其路径上前方出现的障碍物进行检测


寻找上限

一旦障碍物被发现,进行另一个寻找bot上方垂直有效空间的包围体检测


寻找高处通路

通过一系列由低到高的包围体检测扫描竖直空间,来发现第一个畅通无阻的包围体路径


寻找高处通路高度

另一种自下寻找畅通无阻的踪迹,可以找到高处通路的精确高度


寻找高处通路边缘点

最后用一系列向后步进的向下包围体检测高处通路边缘


攀爬展示

从数十个不同高度增量的攀爬动画中选择最接近的匹配动画


(4). 行为和决策



  • 运动: 在场景中控制角色移动到一个新的位置(如冲突解决等)

  • 身体: 控制动画状态

  • 视角: 控制视线,视角以及"我是否能看见xxx"的问题. 维护可识别的实体集

  • 目的: 包含并管理一个并发行为系统(HFSM + Stack)

    • 行为: 包含并管理动作系统

    • 动作: 自发行为模块. 一个动作可以包含一个可并发执行的子动作





动作执行的封装


  • OnStart: 当动作刚刚开始就执行并且可以立即返回转换

  • Update: 动作的执行工作并且可以返回转换到一个新的动作

  • OnEnd: 当动作被转换结束时执行

  • OnSuspend: 当该动作被另一个动作挂起时执行并且可以返回一个转换

  • OnResume: 当动作被挂起后处于暂停时执行并且可以返回一个转换(可能该动作不再有效了)


动作转换


  • Continue(): 没有转换,在下一帧继续执行该动作

  • ChangeTo( NextAction, “reason”): 退出当前动作并且转换到NextAction

  • SuspendFor( NextAction, “reason”): 将当前动作暂时不处理(悬挂)转而进入NextAction

  • Done(“reason”): 动作已经完成. 恢复被悬挂的动作

  • “reason”: 由字符串记录转换发送的原因(例如: “被我追赶的玩家已经死亡”). 字符串原因可以帮助动作系统更加明了并且对于实时进行调试输出是非常珍贵的


动作转换的封装


  • 返回动作的结果会强制执行原子转换,因为在更改为新动作的决策和实际更改之间不能运行任何行为代码

  • 对于从动作A转换到动作B只有一种方法就是由A返回一个转换给B

  • 在没有动作A的认知情况下,没有方法可以强制产生一个由动作A到动作B的转换

  • 将相关的行为代码封装在动作中


事件传播


  • 事件传播是对所有组件而言的

  • 在目的子系统中,事件是:

    • 首先被最内部的子动作操作处理

    • 如果子动作没有回应,事件将会被设至"悬挂动作"

    • 如果"悬挂动作"都没有任何一个回应,事件将会送至父动作





事件举例

OnMoveToSuccess, OnMoveToFailure, OnStuck, OnUnStuck, OnAnimationActivityComplete, OnAnimationEvent, OnContact, OnInjuered, OnKilled, OnOtherKilled, OnSight, OnLostSight, OnSound, OnPickUp, OnDrop



  • 动作可以实现事件触发(Event Handler),为游戏事件提供特定的上下文响应


上下文查询系统


  • 动作可以实现查询方法,为提出的问题提供特定的上下文答案

  • 将可以向行为或动作系统提出的查询定义为“黑匣子”

  • 查询从最内部动作向外传播,直到给出一个答案,这与事件传播相同

  • 允许并发行为进行协调

    • 例如: 我们有机会捡起一个物体,如何?




查询举例


  • SelectMoreDangerousThreat( me, subject, threat1, threat2): 允许电脑Bot发现对其他人最危险的威胁

  • ShouldPickUp (是否应该捡起)

  • ShouldHurry (是否应该快点跟上)

  • IsHindrance (是否是障碍)


三. Provide Competent Human Player Proxies


幸存者Bot



  • 允许我们假定4个玩家幸存者团队进行游戏调整和平衡

  • 在野外非常有帮助

  • 让4个幸存者Bot进行压力测试进而加快时间进度


信任/公平



  • 玩家需要相信电脑bot的在己方时是公平的

  • 模拟不完美的感官认知

  • 模拟瞄准

  • 反映时间

  • 可靠性并且可预测决策

    • 困难点: 拯救倒地的人类




信任



  • 游戏的合作性要求幸存者团队的紧密协作和对队友行动的选择有潜在信任

  • 幸存者Bot会优先考虑人类队友而不是bot

  • 游戏内的“小作弊”以保证一些不希望发生的事件不会发生

    • 幸存者Bot不会不友好地进行开火伤害

    • 幸存者Bot不会使用燃烧瓶

    • 如果一个幸存者Bot出于任何原因离当前地方很远,它将会在人类玩家中没有看向它时传送至小队附近




幸存者Bot进行了复杂性封装



  • 两个并发行为系统: MainLegs



    • Main: 首要进行决策, 注意力, 目标选择和攻击

    • Legs: 受Main所控制,负责与团队保持紧密联系,除非另有指示



  • 许多分层的行为状态对各类游戏事件做出反应



    • 例如: 打断、恢复



  • 复杂的上下文决策



    • Tank/Witch/Boomer/Smoker/Hunter/Mob冲锋、巡逻;幸存者队友道具清理、自救、救人、武器选择、营救、陷害、跛行;处理复杂3D地形、移动物理障碍、火堆、梯子、电梯;以上任意组合



  • 基于实际游戏体验来复刻人类表现



    • 构建的行为系统为重现玩家在玩游戏时做出的决定和动作。




四. Promote Replayability



  • 可重玩性促使玩家长期在游戏上投入, 从而使游戏社区持续增长



    • 持续增长的在线社区促进销量提升

    • 创造新的周边业务



  • 例如: CS、Team Fortress、Day of Defeat



    • 销售收入伴随在线社区增长

    • 极少的地图满足玩家若干年的反复挑战

    • 由玩家团队之间的交互所创造的不可预测的体验推动了可重玩性



  • 在求生之路中程序化的敌人和生成的战利品会极大的提升耐玩度



    • 构建不可预知的遭遇战斗,类似于CS、TF、DoD

    • 游戏挑战被视作技巧挑战而不是背板



  • 静态的敌人和战利品不利于可玩性



    • 玩家擅长记忆静态位置

    • 消除了未知情况的悬念

    • 造成每次游戏都选择"最优策略"

    • 玩家期望每人都有相同的熟练记忆

    • 扼杀团队合作会导致成竞争



  • 即使有多类手动设置的触发器、脚本也无济于事



    • 玩家会学会一切。一旦他们没遇到A,他们就会准备迎接B或C等



  • 我们如何实现基于程序化并且有趣的怪物分布呢?



    • 使用结构性未知

    • 使用系统集合中的"AI Director"



  • 首先, 对于生成结构性未知的工具总结



    • 导航网格

    • 流程距离

    • 潜在可见性

    • 可活动区间




导航网格



  • 描述可行走空间

  • 起源于CS中电脑Bot的寻路

  • 有助于空间推理和空间局部信息获取

    • 区域A是否已经被角色B看见?

    • 获取X对于区域Y是否潜在性可见?

    • 靠近却不被幸存者看见的区域在哪?

    • 到达某区域需走多远?





流程距离



  • 在导航网格中从起始安全房间到其他每个区域的移动距离

  • 引导逐渐增加流程梯度总会将你带到出口房间

  • “逃跑路径” = 从起始点到出口的最短距离

  • 用于作为敌人和战利品生成的参照,并且可用于回答"这个区域在幸存者团前方还是后方"的问题



可活动区间(AAS)



  • 包围幸存者团队的导航区域集

  • AI Director根据AAS在环境中移动创建、销毁刷怪点

  • 利用一个很小的对象池允许对成百上千的敌人复用



潜在可见性



  • 对任意一个幸存者潜在可见的区域组成的集合


可活动区间


通过结构性未知做程序化生成



  • 并非随机,也不是固定

  • 基于空间或时间变化依据策划定义的随机量的生成函数

    • 例: 怪物批次

    • 在90到180秒见随机间隔发生

    • 在幸存者"后方"随机生成



  • 结构化未知 = 上述算法有限次叠加组合


求生之路的结构性未知策略



  • 巡逻怪(高频)

    • 普通被感染者会游荡巡逻直到看见幸存者



  • 聚众怪(中频)

    • 一大群(20-30个)被感染者周期性的冲向幸存者



  • Boss(低频)

    • 强力的被感染者会驱使幸存者改变策略



  • 武器库(低频)

    • 更有效的武器集



  • 批量杀伤性武器(中频)

    • 炸弹、燃烧瓶、止痛药、肾上腺素等




巡逻怪生成策略



  • 在区域中简单存储为一个数量(N)



  • 地图开始时基于逃生路径长度和期望密度随机决定数量



  • 区域进入AAS



    • (如果可行) 创建N个被感染者



  • 区域离开AAS, 或有等待群聚的怪



    • 区域中的巡逻怪被删除且N因此增大



  • 巡逻怪数量(N)清零



    • 当区域对任意幸存者可见时

    • 当Director处于Relax模式时





    • 绿色区域进入AAS且巡逻怪开始生成

    • 红色区域离开AAS且被感染者将被清除





群聚怪生成策略



  • 在一定时间间隔内随机生成(普通难度为90-180秒)

  • Boomer Vomit强制暴走怪开始袭来,重置随机间隔

  • 群聚怪规模在刚打到顶峰后间隔片段从谷低值开始再次增长, 用以平衡群聚怪连续程度


特殊感染怪生成策略



  • 在随机时间间隔点单个生成

  • 依不同特殊类型使用对幸存者不可见的有效AAS

    • Boomer因其不善于追赶故迎面袭击

    • Smoker尝试选择高于幸存者队伍的地段




从哪开始袭击



  • 抄幸存者后路



    • 仅选取处于幸存者队伍流程距离或其后的有效AAS

    • 巡逻怪和特殊感染怪、Boss经常抄前路、75%的群聚怪选择抄后路



  • 抄幸存者前路



    • 仅选取处于幸存者队伍流程距离或其前方的有效AAS



  • 近距Boomer Vomit Victim



    • 仅选取处于Boomer Vomit Victim流程距离附近的有效AAS



  • 任意位置



    • 任意有效AAS

    • 若特定集合不存在有效区域则以此策略默认




Boss生成策略



  • 在逃生路上每隔N个单位生成一个,进入地图开始时+/-随机数量

  • 三个Boss事件乱序并执行: Tank、Witch、无

  • 不允许连续相同的生成(例:Tank,然后还是Tank)


武器库



  • 地图策划在每张地图中创建若干个可能的武器库,AI Director从中挑选哪些将存在


批量杀伤性武器



  • 地图策划在每张地图中穿插若干组可能的批量杀伤性武器,AI Director从中挑选哪些组将存在


为何策划放置?



  • 预设位置适用于此类物体

  • 允许可视化叙事/交代

  • 解决道具放置问题(斜靠着墙,置于枪架上等)


程序化内容



  • 促进可玩性

  • 带来线性的,引人入胜的多人游戏体验

  • 增加游戏制作团队产出

  • 鼓励社区自制内容


五. Generate Dramatic Game Pacing



  • 什么叫 “引入注目的游戏节奏感”?

    • 在运行时依算法调节游戏节奏以最大化让玩家投入进游戏(玩家体会激动、刺激)



  • 灵感来源于CS

    • 在CS中节奏比较固定,在平静的紧张氛围下,不时会出现一些剧烈的时刻

    • 一成不变的战斗是令人疲惫的

    • 长时间的不活动是无聊的

    • 出乎意料的峰谷交错节奏产生了耐玩的体验

    • 相同的场景,通常是相同的地图,但每一轮都有与众不同的经验。




自适应节奏算法



  • 创建类似于CS这样成功的跌宕起伏强烈节奏的

  • 算法:

    • 评估每个幸存者的"心情程度"

    • 跟着四名幸存者中心态程度最大值

    • 如果数值过高,这段时间移除主要威胁

    • 否则创建一大批令人感到威胁的怪



  • 另外一个关键系统"AI Director"


评估每名幸存者的"心情程度"



  • 将每名玩家心情值量化

  • 提高幸存者心情值

    • 当被攻击时,会受到一定比例伤害

    • 丧失战斗能力(倒地)

    • 当幸存者在平台边缘被怪推搡时

    • 当附件的怪死掉时,与距离成比例



  • 幸存者"心情程度"随时间衰减直至0

  • 当有怪威胁到幸存者时不进行处理


依幸存者激动程度调节怪生成策略



  • 逐渐提高

    • 持续生成对幸存者造成威胁直到超过幸存者心情值的最高峰



  • 维持

    • 当幸存者心情值达到波峰持续3到5秒全力进攻

    • 确保最小"逐渐提高"的过程



  • 逐渐降低

    • 切换至最小威胁(“放松阶段”)并监控玩家心情值直至衰减至波峰范围外

    • 这种状态对于当前的战斗交战是必要的,可以在不消耗整个放松阶段的情况下发挥出来。高峰淡出不会允许放松阶段开始,直到一个行为发生产生了自然打断。



  • 放松

    • 维持最小的威胁30-45秒,若幸存者已基本跑到下一处安全房间则重新回到"逐渐提高"





满状态威胁阶段怪

- 巡逻怪
- 群聚怪
- 特殊感染怪

最小威胁阶段(放松)

- 无巡逻怪直到小队平静时
- 无群聚怪
- 无特殊感染怪(残余部队将继续进攻)

不受节奏阶段影响的Boss怪

- 如果Boss消失,整体节奏感就会影响很多
- 遭遇Boss会让整个节奏感进行改变

AI Director如何依幸存者团队“心情程度”调节生成策略


自适应引人入胜的节奏感在于幸存者队伍



  • 不需要压倒性的压力就可以让队伍体验紧张的战斗节奏

  • 因玩家每次的行动和程序化生成都千差万别,每次游戏过程体验不同


算法调整节奏而不是难度



  • 节奏幅度(难度)恒定,频率(节奏)会改变


简单的算法可产生深刻的节奏



  • 幸存者心情程度只是粗略估计,然而调节节奏感是有效的


这只是个起点



  • 扩大AI可用的动词库

  • 进一步探索程序内容生成的机会

  • 如何在其他游戏项目中使用这些系统?


翻译完毕…乘着每天下班回家后的1-2个小时功夫终于翻译完了…当然有些地方理解以及翻译可能存在误解,有不理解的可以自行找到对应PPT理解…




推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
author-avatar
英萍维玟9856
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有