AI:游戏AI基础概念

Reading time ~1 minute

Artificial Intelligence(AI),是一个复杂高深的课题,应用在许多领域,在游戏中自然也有重要的作用。本质上来说,AI就是让计算机能像生物一样进行思考和决定来执行某些特定操作。除了游戏特定的技术,AI还应用到了计算机视觉、自然语义处理、机器学习等许多领域。 这个系列,我们主要就是参考《Unity AI Game Programming Sencond Edition》,介绍如何在Unity中实现一些AI技术。

定义agent

在开始前,我们先要介绍一个将会频繁使用到的术语 - agent。Agent对于AI来说,就是我们的人工智能实体。当我们讨论AI时,并不是特指某个角色,而是一个表现复杂行为模式的实体,这个实体可以是角色、动物、交通工具等等任何东西。Agent会自主的执行我们赋予的模式和行为。

有限状态机(Finite State Machines)

Finite State Machines (FSM)可以被认为是最简单的AI模型。一个状态机基本由一组状态(state)组成,这组状态由它们之间的转移(transition)来连接。一个游戏实体任一时刻只能处于一个状态。 FSM十分容易实现并且易于理解,只要使用if/else或者switch就可以创建FSM。但随着状态和转移的增多,状态机会变得越来越混乱。后面我们会详细介绍如何实现简单的状态机。

通过agent观察世界

为了使AI更有说服力,我们的agent也需要能对周围环境、角色的事件产生回应。好像生物一样,agent也可以依靠看、听或其他“感官”。视觉、听觉或其他感觉,本质上也是数据。然而模拟真实的数据是非常复杂的,但我们仍可以通过一些方法模拟数据来产生类似的结果。

路径跟踪和驾驶

有时,我们需要AI能在游戏世界中根据预定的路径行走。比如赛车比赛中的对手,或是RTS游戏中的单位通过地形和其他单位导航到特定位置。 为了展现智能,agents要能决定自己要到哪、是否能到达,寻找最有效率的路径,并且遇到障碍可以绕过。 后面我们会介绍A*寻路系统,以及Unity内置的navigation mesh (NavMesh)功能。

A*寻路

A是一种寻路算法,因为其性能和精度广泛用于游戏中。我们来看个简单例子了解它是如何工作的。假设我们想让单位从A移动到B,但中间有堵墙挡着不能直接过去,这是就要找到一条路绕过去。 我们先把整个地图划分成许多小格,使地图成网格形(当然也可以划分成别的如六边形、三角形),这样会令搜索地图更加简单,这是非常重要的一步。 然后我们就可以开始寻找最佳路径,通过计算每一格距离无障碍的起始格的移动分数,选择最少的消耗的格子。我们会在后面详细介绍A的实现方法。

A*需要通过大量计算得出最佳路径。于是为了更简单快速,人们又想出了通过路径点来查找路径的方法。还是假设上面的从A点到B点的例子,这时我们可以使用三个路径点。

我们现在要做的是找到最近的路径点然后跟随它的连接网点到达目的地。使用路径点计算更加高效,但也有问题,比如当障碍更新,路径点也要必须更新。

AI在两个节点间是走直线的,如果路径离墙很近那么AI就可能撞到墙上并卡住。虽然我们可以调整路径来躲避障碍,但问题是路径点并不能提供环境信息,如果我们调整的路径是在悬崖或是桥边呢?这样的路径并不安全。如果我们想让AI能有效的行动,就需要大量的路径点,但这是非常难以实现和管理的。

这时使用NavMesh就会更加合理。NavMesh是另一种表示游戏世界的图表结构。如下所示:

一个navigation mesh使用凸面多边形(convex polygons)来表示AI实体可以通过的地形区域。navmesh最重要的优点是相比路径点,可以提供许多环境信息。现在我们可以安全的调整我们的路径因为我们知道哪块区域是可以通过的。另一个好处是,使用navmesh,同样的mesh可以用于不同AI实体。 但是通过编程对场景生成navmesh是比较复杂的处理。不过幸运的是,Unity中已经自带了这一功能。后面我们将详细介绍。

集群(flocking)和人群动力学(crowd dynamics)

许多生物比如鸟、鱼、昆虫等都会成组的执行某些行为。假如我们想模拟一群鸟在空中飞翔,如果对每个鸟都做动画实现,那是非常困难的。我们可以对每个鸟应用一些规则,就可以达到自然群聚的智能行为。 同样的,一大群人,相比于控制每一个人的行为,模拟整个人群的行为更为可行。群组中的每个个体,只需要知道整个群组的方向和自己最相邻的个体的目的来实现整个系统的功能。

行为树(Behavior trees)

行为树是另一个表示和控制AI逻辑行为的模式。前面我们大概介绍了FSM,这是一种非常简单但高效的方法来定义agent的行为。但是FSM很难调整,因为它们很快就会变得很笨拙而且需要大量手动设置。我们需要一种可扩展的方法来解决大量问题的情景。这就是行为树提出的背景。
行为树是节点的集合,以分层顺序组合,不同于状态互相连接,它是节点连接到父节点,就好像树一样。
行为树的基本元素是任务节点。有许多不同的任务,比如序列(Sequence)、选择器(Selector)和平行装饰(Parallel Decorator)等。 首先来看一下选择器。如图,用圆形表示选择器。它会按从左到右顺序评估子节点。首先选择attack,如果返回成功,选择器就完成并返回父节点。如果attack返回失败,就继续尝试Chase任务。同理,chase返回失败就继续尝试Patrol。

接下来看一下序列任务,通过内部带箭头的矩形表示。根选择器会选择第一个序列事件来执行。这个序列事件第一个任务是检测是否足够近以实施攻击,如果任务成功,会继续下一个任务,即攻击 。如果攻击也返回成功,则整个序列任务成功,选择器结束并不会执行其他序列事件。如果第一个检测距离任务失败,则第一个序列事件失败,选择器会选择下一个序列事件执行。

另外两个常用组件是平行任务和装饰。平行任务会同时执行所有它的子任务,而选择器和序列只会依次的执行子任务。装饰是另一种类型的任务,它只有一个子节点。它可以更改子节点任务的行为,比如对于子任务是否执行、何时执行等。 后面我们会更详细的介绍行为树。

以模糊逻辑思考

最后,我们来介绍模糊逻辑。简单的说,模糊逻辑指的是近似输出而不是标准的二进制结果。 假设我们Agent是一个敌人士兵,无论它使用了FSM还是行为树,它都要作出许多决定。比如是否转换到状态a/b/c?这个任务返回true还是false?没有使用模糊逻辑时,我们需要一个二进制值来解答这些问题。比如这个士兵是否看到了玩家?答案是一个yes/no的二进制状态。但我们可以进一步抽象这个决定,来使士兵完成一些有趣的行为。当士兵确定能看到主角时,它可以问自己是否有足够的弹药、是否有足够的生命值完成战斗、主角是否有其他盟友在周围等。这样,我们的AI就会变得更加有趣、不可预测且更可信。

总结

学术AI和游戏AI有着许多不同之处。学术AI主要解决真实世界的问题和提出一些没有资源限制的理论。而游戏AI主要专注于在有限资源下构建有人工智能的NPC。游戏AI的目的主要是提供有挑战性的对手来使游戏更有趣味。 在后面的内容,我们会分别介绍上面提到的这些AI技术。

Scriptable Objects 及 游戏架构

Scriptable Objects 相关介绍,及基于其的游戏架构技术 Continue reading

AssetBundle 最佳实践

Published on January 29, 2019

AssetBundle 基础总结

Published on January 27, 2019