您可以在此处下载已完成的项目。
请查看环境查询系统
下载启动项目并解压缩。导航到项目文件夹并打开MuffinWar.uproject。
按播放开始游戏。在围栏区域内左键单击以生成松饼。
在本教程中,您将创建一个会四处游荡的 AI。当敌人的松饼进入 AI 的视野范围时,AI 会移动到敌人并攻击它。
要创建一个 AI 角色,您需要三件事:
既然你已经有了身体,你所需要的只是一个灵魂和大脑。首先,您将创建一个将成为灵魂的 controller。
controller是可以拥有Pawn的非物理角色。Possession 允许控制器——你猜对了——控制Pawn。但在这种情况下,“控制”是什么意思?
对于玩家来说,这意味着按下一个按钮并让 Pawn 做一些事情。控制器从玩家接收输入,然后它可以将输入发送到 Pawn。控制器也可以改为处理输入,然后告诉 Pawn 执行操作。
在 AI 的情况下,Pawn 可以从控制器或大脑接收信息(取决于您如何对其进行编程)。
要使用 AI 控制松饼,您需要创建一种特殊类型的控制器,称为AI controller。
导航到Characters\Muffin\AI并创建一个新的Blueprint Class。选择AIController作为父类并将其命名为AIC_Muffin。
接下来,您需要告诉松饼使用您的新 AI 控制器。导航到Characters\Muffin\Blueprints并打开BP_Muffin。
默认情况下,详细信息面板应显示蓝图的默认设置。如果没有,请单击工具栏中的Class Defaults 。
转到 Details 面板并找到Pawn部分。将AI Controller Class设置为AIC_Muffin。这将在松饼生成时生成控制器实例。
由于您正在生成松饼,因此您还需要将Auto Possess AI设置为Spawned。这将确保AIC_Muffin在生成时自动拥有BP_Muffin。
单击编译,然后关闭BP_Muffin。
现在,您将创建驱动松饼行为的逻辑。为此,您可以使用behavior trees。
导航到Characters\Muffin\AI并选择Add New\Artificial Intelligence\Behavior Tree。将其命名为BT_Muffin,然后打开它。
行为树编辑器包含两个新面板:
与蓝图一样,行为树由节点组成。行为树中有四种类型的节点。前两个是 tasks and composites。
顾名思义,任务是“做”某事的节点。这可能是复杂的事情,例如执行组合。也可以是简单的事情,例如等待。
要执行任务,您需要使用组合。行为树由许多分支(行为)组成。每个分支的根部是一个复合体。不同类型的组合有不同的方式来执行它们的子节点。
例如,您有以下一系列操作:
要执行序列中的每个操作,您将使用Sequence 组合。这是因为序列从左到右执行其子级。这是它的样子:
注意:从组合开始的所有内容都可以称为子树。一般来说,这些是你的行为。在这个例子中,Sequence、Move To Enemy、Rotate Towards Enemy和Attack可以被认为是“攻击敌人”的行为。如果序列的任何子节点失败,序列将停止执行。
例如,如果 Pawn 无法移动到敌人身边,Move To Enemy将失败。这意味着Rotate Towards Enemy和Attack不会执行。但是,如果 Pawn 成功移动到敌人身边,它们将执行。
稍后,您还将了解Selector组合。现在,您将使用Sequence使 Pawn 移动到随机位置,然后等待。
创建一个Sequence并将其连接到Root。
接下来,您需要移动 Pawn。创建一个MoveTo并将其连接到Sequence。该节点会将 Pawn 移动到指定的位置或Actor。
然后,创建一个Wait并将其连接到Sequence。确保将其放置在MoveTo的右侧。顺序在这里很重要,因为孩子们会从左到右执行。
注意:您可以通过查看每个节点右上角的数字来检查执行顺序。编号较低的节点优先于编号较高的节点。
恭喜,您刚刚创建了您的第一个行为!它会将 Pawn 移动到指定位置,然后等待五秒钟。
要移动 Pawn,您需要指定一个位置。但是,MoveTo只接受通过黑板提供的值,因此您需要创建一个。
黑板是一种资产,其唯一功能是保存变量(称为键)。你可以把它想象成人工智能的记忆。
虽然您不需要使用它们,但黑板提供了一种方便的方式来读取和存储数据。这很方便,因为行为树中的许多节点只接受黑板键。
要创建一个,请返回Content Browser并选择Add New\Artificial Intelligence\Blackboard。将其命名为BB_Muffin,然后打开它。
黑板编辑器由两个面板组成:
现在,您需要创建一个保存目标位置的密钥。
由于您将位置存储在 3D 空间中,因此您需要将其存储为矢量。单击New Key并选择Vector。将其命名为TargetLocation。
接下来,您需要一种方法来生成随机位置并将其存储在黑板上。为此,您可以使用第三种类型的行为树节点:服务。
服务就像您使用它们做某事的任务。但是,您使用服务来执行检查或更新黑板,而不是让 Pawn 执行操作。
服务不是单独的节点。相反,它们附加到任务或组合上。这会产生更有条理的行为树,因为您需要处理的节点更少。以下是使用任务的外观:
以下是使用服务的外观:
现在,是时候创建一个生成随机位置的服务了。
返回BT_Muffin并单击New Service。
这将创建一个新服务并自动打开它。将其命名为BTService_SetRandomLocation。您需要返回内容浏览器来重命名它。
该服务只需要在 Pawn 想要移动时执行。为此,您需要将其附加到MoveTo。
打开BT_Muffin,然后右键单击MoveTo。选择Add Service\BTService Set Random Location。
现在,BTService_SetRandomLocation将在MoveTo激活时激活。
接下来,您需要生成一个随机目标位置。
打开BTService_SetRandomLocation。
要知道服务何时激活,请创建一个Event Receive Activation AI节点。这将在服务的父节点(它所连接的节点)激活时执行。
注意:还有另一个称为Event Receive Activation的事件可以做同样的事情。这两个事件的区别在于Event Receive Activation AI还提供了Controlled Pawn。
要生成随机位置,请添加突出显示的节点。确保将Radius设置为500。
这将在 Pawn 的500个单位内为您提供一个随机的可导航位置。
注意: GetRandomPointInNavigableRadius使用导航数据(称为NavMesh)来确定一个点是否可导航。在本教程中,我已经为您创建了 NavMesh。您可以通过转到 Viewport 并选择Show\Navigation来可视化它。
如果您想创建自己的 NavMesh,请创建Nav Mesh Bounds Volume。缩放它,使其封装您想要导航的区域。
接下来,您需要将位置存储到黑板上。有两种方法可以指定使用哪个键:
您将使用第二种方法。创建Blackboard Key Selector类型的变量。将其命名为BlackboardKey并启用Instance Editable。当您在行为树中选择服务时,这将允许变量出现。
然后,创建突出显示的节点:
概括:
单击编译,然后关闭BTService_SetRandomLocation。
接下来,您需要告诉行为树使用您的黑板。
打开BT_Muffin并确保您没有选择任何东西。转到详细信息面板。在Behavior Tree下,将Blackboard Asset设置为BB_Muffin。
之后,MoveTo和BTService_SetRandomLocation将自动使用第一个黑板键。在这种情况下,它是TargetLocation。
最后,您需要告诉 AI 控制器运行行为树。
打开AIC_Muffin并将Run Behavior Tree连接到Event BeginPlay。将BTAsset设置为BT_Muffin。
这将在AIC_Controller生成时运行BT_Muffin。
单击编译,然后返回主编辑器。按Play,生成一些松饼,看着它们四处游荡。
这是很多设置,但你到了那里!接下来,您将设置 AI 控制器,以便它可以检测到其视野范围内的敌人。为此,您可以使用AI Perception。
AI Perception 是一个可以添加到 actor 的组件。使用它,您可以为您的 AI 赋予感官(例如视觉和听觉)。
打开AIC_Muffin,然后添加一个AIPerception组件。
接下来,您需要添加一种感觉。由于您想检测另一个松饼何时进入视野,因此您需要添加视觉。
选择AIPerception,然后转到详细信息面板。在AI Perception下,向Senses Config添加一个新元素。
将元素0设置为AI Sight 配置,然后展开它。
视线有三个主要设置:
默认情况下,AI 感知仅检测敌人(分配给不同团队的演员)。但是,演员默认没有团队。当演员没有团队时,AI Perception 认为它是中立的。
在撰写本文时,还没有使用蓝图分配团队的方法。相反,您可以告诉 AI Perpcetion 检测中立的演员。为此,请展开Detection by Affiliation并启用Detect Neutrals。
单击编译,然后返回主编辑器。按播放并生成一些松饼。按 ' 键显示 AI 调试屏幕。按数字键盘上的4以可视化 AI 感知。当松饼进入视野时,会出现一个绿色球体。
接下来,您将松饼移向敌人。为此,行为树需要了解敌人。您可以通过在黑板上存储对敌人的引用来做到这一点。
打开BB_Muffin,然后添加一个Object类型的键。将其重命名为Enemy。
现在,您将无法在MoveTo中使用Enemy。这是因为键是Object但MoveTo只接受Vector或Actor类型的键。
要解决此问题,请选择Enemy,然后展开Key Type。将Base Class设置为Actor。这将允许行为树将Enemy识别为Actor。
关闭BB_Muffin。现在,您需要创建一个行为以向敌人移动。
打开BT_Muffin然后断开Sequence和Root。您可以通过按住 alt 键单击连接它们的线来完成此操作。暂时将漫游子树移到一边。
接下来,创建突出显示的节点并将其Blackboard Key设置为Enemy:
这会将 Pawn 移向Enemy。在某些情况下,Pawn 不会完全面向其目标,因此您还可以使用Rotate 来面对 BB entry。
现在,当 AI Perception 检测到另一个松饼时,您需要设置Enemy 。
打开AIC_Muffin,然后选择AIPerception组件。添加一个On Perception Updated事件。
每当感知更新时,都会执行此事件。在这种情况下,每当人工智能看到或看不见某物时。此事件还提供了它当前感知的Actor列表。
添加突出显示的节点。确保将Make Literal Name设置为Enemy。
这将检查 AI 是否已经有敌人。如果没有,你需要给它一个。为此,请添加突出显示的节点:
概括:
单击编译,然后关闭AIC_Muffin。按播放,然后生成两个松饼,使一个在另一个前面。后面的松饼会自动走向另一个松饼。
接下来,您将创建一个自定义任务以使松饼执行攻击。
您可以在内容浏览器而不是行为树编辑器中创建任务。创建一个新的蓝图类并选择BTTask_BlueprintBase作为父级。
将其命名为BTTask_Attack然后打开它。添加一个事件接收执行 AI节点。该节点将在行为树执行BTTask_Attack时执行。
首先,您需要制作松饼攻击。BP_Muffin包含一个IsAttacking变量。设置后,松饼将执行攻击。为此,请添加突出显示的节点:
如果您在当前状态下使用任务,执行将卡在它上面。这是因为行为树不知道任务是否已经完成。要解决此问题,请将Finish Execute添加到链的末尾。
接下来,启用Success。由于您使用的是Sequence,这将允许BTTask_Attack之后的节点执行。
这就是你的图表应该是这样的:
概括:
单击编译,然后关闭BTTask_Attack。
现在,您需要将BTTask_Attack添加到行为树中。
打开BT_Muffin。然后,在Sequence的末尾添加一个BTTask_Attack
接下来,将Wait添加到Sequence的末尾。将其等待时间设置为2。这将确保松饼不会不断攻击。
返回主编辑器并按Play。像上次一样产生两个松饼。松饼会向敌人移动并旋转。之后,它会攻击并等待两秒钟。如果它看到另一个敌人,它将再次执行整个序列。
在最后一节中,您将把攻击和漫游子树组合在一起。
要组合子树,您可以使用Selector组合。与序列一样,它们也从左到右执行。但是,当子成功而不是失败时,选择器将停止。通过使用此行为,您可以确保行为树只执行一个子树。
打开BT_Muffin ,然后在Root节点之后创建一个Selector 。然后,像这样连接子树:
这种设置一次只允许运行一个子树。以下是每个子树的运行方式:
返回主编辑器,按Play。产生一些松饼来测试它。
“等一下,松饼为什么不立即攻击另一个?”
在传统的行为树中,每次更新都从根开始执行。这意味着每次更新,它都会先尝试攻击子树,然后再尝试漫游子树。这意味着如果Enemy的值发生变化,行为树可以立即更改子树。
但是,虚幻的行为树的工作方式不同。在 Unreal 中,从最后执行的节点开始执行。由于 AI 感知不会立即感知其他参与者,因此漫游子树开始运行。行为树现在必须等待漫游子树完成,然后才能重新评估攻击子树。
要解决此问题,您可以使用最终类型的节点:装饰器。
像服务一样,装饰器附加到任务或组合上。通常,您使用装饰器来执行检查。如果结果为真,装饰器也将返回真,反之亦然。通过使用它,您可以控制装饰器的父级是否可以执行。
装饰器还具有中止子树的能力。这意味着一旦设置了Enemy,您就可以停止漫游子树。这将允许松饼在检测到敌人后立即攻击敌人。
要使用中止,您可以使用Blackboard装饰器。这些只是检查是否设置了黑板键。打开BT_Muffin,然后右键单击攻击子树的序列。选择Add Decorator\Blackboard。这会将 Blackboard 装饰器附加到序列。
接下来,选择Blackboard装饰器并转到 Details 面板。将Blackboard Key设置为Enemy。
这将检查是否设置了 Enemy。如果没有设置,装饰器会失败,导致Sequence失败。这将允许漫游子树运行。
为了中止漫游子树,您需要使用Observer Aborts设置。
如果选定的黑板键已更改,观察者中止将中止子树。有两种类型的中止:
将Observer Aborts 设置为Both。这将启用两种中止类型。
现在,如果攻击子树不再有敌人,它可以立即进入漫游状态。此外,一旦检测到敌人,漫游子树可以立即进入攻击模式。
这是完整的行为树:
攻击子树总结:
漫游子树总结:
关闭BT_Muffin,然后按Play。生成一些松饼,为有史以来最致命的大逃杀做好准备!