7 - AI入门
本文将初步介绍UE5中有关人工智能系统的入门知识,例如AI控制器AIController
,黑板Blackboards
和行为树的概念及简单使用。
AI Controller
PlayerController
和AIController
这两个Actor
类都继承自AController
基类,AController
可以用来控制Pawn
或者Character
的动作。玩家控制器依赖于实际玩家的输入,而AI控制器通过运用人工智能来操控其拥有的角色,并根据设定好的规则对环境作出反应。一个AI控制器可由相同AI Pawn的多个实例使用,并且相同的AI控制器可在不同的AI Pawn类中使用。
主动拥有Pawn
在C++中,可用Possess()
来拥有一个Pawn:
void AController::Possess(APawn* InPawn);
可用UnPossess()
解除Pawn的拥有状态:
void AController::UnPossess();
在调用Possess()
或UnPossess()
的同时,也会触发OnPossess()
或OnUnPossess()
回调。
导航网格体 NavMesh
UE5通过导航网格体NavMesh告诉人工智能哪些环境是可导航的,而哪些环境是不可导航的。UE5还支持动态的NavMesh,它支持动态对象在环境中移动时实时更新NavMesh,这使得AI能够识别环境变化,并适应导航路径。
在引擎中拖入一个NavMesh,让它和地面相交,然后按下P键启用导航Debug视图,出现的绿色便是可导航的区域。效果如下:
RecastNavMesh
在创建NavMesh的同时,一个名字为RecastNavMesh-Default
的Actor被自动创建。这个RecastNavMesh
可以被视为NavMesh的“大脑”,它包含了调整NavMesh所需的参数,这些参数将直接影响AI如何在给定区域中导航。
RecastNavMesh
包含的参数很多,常用到的参数如下:
- 显示 Display:影响可视化调试
NavMeshBoundsVolume
生成的导航区域,方便debug。 - 生成 Generation:决定NavMesh如何生成,以及确认哪些区域是可导航的,哪些不是。常用到的参数如下:
- Cell Size:NavMesh在给定空间中生成可导航区域的精度;
- Agent Radius:在此区域导航的Actor的半径。
- Agent Height:在此区域导航的Actor的高度。
- Agent Max Slope:游戏世界中可能存在的倾斜角度。
- Agent Max Step Height:AI可以导航到的台阶高度,以楼梯台阶为单位。
行为树和黑板
行为树和黑板协同工作,允许AI遵循不同的逻辑路径,并根据各种条件和变量做出决策。
黑板
黑板是定义变量(也被称为键Key)的地方,方便行为树使用这些变量做决策。
行为树
行为树是一种可视化编程工具,可以根据某些因素和参数告诉Pawn该做什么。它由一组对象组成,即 组合器(Composites),任务(Tasks),服务(Services)和装饰器(Decorators),它们共同定义AI将如何根据设置的条件和逻辑流程进行行为响应。
组合器 Composites
组合器节点告诉行为树如何执行任务和其他操作,也能附加装饰器和服务,以便在执行行为树分支前应用可选条件。
常见的组合器节点如下:
Selector:Selector节点按从左到右的顺序执行其子任务,并在其中一个子任务成功时停止执行之后的子任务。
此外,能在节点右上角处发现数字,这是节点的执行顺序,一般是从上到下、从左到右。
Sequence:Sequence节点从左到右顺序执行其子任务,当其中一个子任务失败将停止执行之后的子任务。
Simple Parallel:可同时执行任务和新的独立逻辑分支。例如下图,Wait任务执行的同时Sequence也在执行:
在“细节”面板中可以调节该节点的
Finish Mode
参数:Immediate
:该节点将在主任务完成后成功完成。例如上图,Wait任务完成后后面的Sequence会自动停止。Delayed
:该节点将在主任务和后面的任务完成后才成功完成。
任务 Tasks
这里提供AI可以完成的任务,UE5默认内置了一些任务,包括移动到特定位置,旋转以面对目标,发射武器等。也能通过在蓝图或C++中创建自己的任务。
例如下图中定义了一个任务,从ReceiveExecuteAI事件开始,基于AI自己Pawn的位置随机生成一个新位置,然后在FinishExecute结束,并返回是否成功。
装饰器 Decorators
装饰器是可以添加到任务或组合器的条件,通常用于实现分支逻辑。除了使用内置的装饰器外,也能通过蓝图自定义装饰器。
服务 Services
和装饰器比较相似,也能添加到任务或组合器间,但服务允许我们基于它定义的间隔执行节点分支。
要想运行行为树,可在AIController中的BeginPlay中调用RunBehaviorTree:
实践
接下来尝试实践一下,实现AI按巡逻点寻路的功能。
首先,新建一个基于Actor的蓝图类BP_AIPoints
,用于存储巡逻点。在这个类上新建一个vector数组Points
,勾选“实例可编辑”和“显示3D控件”。然后新建一个函数GetNextPoint
,用于在Points
中获取一个巡逻点,这个巡逻点是本地坐标的,因此要转换为世界坐标:
然后将这个蓝图类放到地图上,在细节面板中添加数个巡逻点,然后在地图上摆好:
接下来要让敌人的蓝图类引用这个巡逻点实例,新建一个PatrolPoints
变量,引用BP_AIPoints
,别忘了勾选实例可编辑。然后在地图上点击敌人,绑定引用变量。接下来实现敌人的行为树:
其中找到巡逻点的函数如下:
最后编译好蓝图就行了。
参考资料
中文翻译:《UE5 C++ 游戏开发完全学习教程》
英文原版:《Elevating Game Experiences with UE5》