【游戏AI】GOAP 目标导向任务规划(1)

文章讲述了作者在类殖民地建设项目中引入GOAP进行AI设计,描述了GOAP的基本概念、组成元素(如Goal、Action、WorldStates和AgentStates),并计划在Unity中实现单智能体Demo,实验结果显示基本符合预期,但发现一个小Bug,后续将探索HTN和优化GOAP实现。
摘要由CSDN通过智能技术生成

概要

最近在开展一个类殖民地建设项目的前期研究,想引入类似于缺氧中的游戏AI,主要是需要按照待办的任务来按次序开展,并且多个智能体之间要能够形成合理的任务分配和协作。

由于我们想要实现的AI需要完成大量复杂任务,出于可扩展性的角度考虑,基础的状态机和行为树明显是不适合这类复杂AI的,所以至少应该从HTN和GOAP出发。读了一些文章,暂时的想法是由GOAP系统来实现单个智能体的行为,由HTN系统来实现多智能体的群体管理。

先从GOAP开始学习研究。

在这里插入图片描述

什么是GOAP?

目标导向的任务规划 (Goal-Oriented Action Planner, GOAP) 是一种较复杂AI的实现方案。基于此方案的游戏AI从需要实现的Goal出发,去自发地构建一个Plan。这个Plan中包含一系列有序排列的Action。智能体将按照这个Plan逐个完成其中的Action,然后再去满足下一个Goal,并不断反复。

GOAP系统组成

Goal目标

设计者希望智能体能够达成的目标,比如完成采矿,完成建造等。

游戏AI通常具有多个优先级不同的目标,一般按照预设的固定优先级来逐个满足目标。

有时候也会采用动态优先级,但根据我自己的理解,这种动态调整是一种低频调整,例如Boss在低血量状态下的行动模式调整。算法在正常执行过程中大多数时间应该是保证固定优先级的。

Action行动

设计者希望智能体能够执行的实际操作和行为。智能体要开展某个行动,必须要满足开展此行动的前提条件Pre Conditions,行动成功后,此行动将产生某种影响,具体来说是对状态的改变,这种影响叫作After Effects。

After Effects可以改变智能体自身的状态,也可以改变世界状态。

World States世界状态

世界状态是被所有智能体共享的状态,常见的例子是资源总量。现在总共有10个矿物,A智能体拿走了这10个矿物去盖了个房子,B智能体就不能使用这个矿物了。世界状态的改变会影响所有智能体的后续行为。

Agent States智能体状态

智能体状态是智能体自己的状态,比如饱食度,疲劳值等。当一个智能体的饱食度过低时,它可能会尝试进食。智能体状态只直接影响智能体自身,不影响其他智能体。

Sensor感知器

感知器主要是去观测一些变量,来判断当前的状态是否已经发生了改变。通常来说,世界和智能体都包含许多变量,但不是所有变量都会影响状态,一个状态也不只由一个变量决定。比如危险状态,并不一定只存在一种固定的模式,可能在多种情况下智能体都会转变为危险状态。因此需要Sensor去订阅我们想要观测的变量,相当于一段将变量的数据映射到状态的处理程序。

实验设计

我打算在Unity中写一个小Demo,来验证GOAP系统在单智能体情况下的运行情况。

GOAP系统主要使用SGOAP这个Unity Package,具体程序接口请参阅他们的文档和教程(https://assetstore.unity.com/packages/tools/behavior-ai/s-goap-ai-solution-167167)

实验中包含的Goal,Action等信息具体如下表所示:

目标Goal优先级Priority
Full 吃饱3
Build 建造2
Mineral 获取矿物1

智能体最优先保证自己能吃饱,然后是去建造,最后是去挖矿,都不能实现就什么都不做。

行动Action前置条件Pre Conditions完成后影响After Effects
Eat 吃饭Hunger < 20, AtEatPlace == trueHunger = 100, Full
Build 建造Mineral >= 2, AtBuildPlace == true, BuildWaiting >= 1Build += 1
Mineral 获取矿物AtMinePlace == true, MineWaiting >= 1Mineral += 1
GoToEat 前往餐区Hunger < 20, AtEatPlace == falseAtEatPlace == true
GoToBuild 前往建造区BuildWaiting >= 1, Mineral >= 2, AtBuildPlace == falseMineral += 1
GoToMine 前往矿区MineWaiting >= 1, AtMinePlace == falseMineral += 1

吃饭、建造、挖矿都需要在对应的区域完成,如果智能体当前不在工作区域,则要求智能体先移动到工作区域。饥饿值低于20之后就要去吃饭,建造需要消耗两个矿物。实验中还模拟了玩家选中需要被开采的矿物和需要建造的建筑这一操作。只有当待开采矿物和待建建筑 >= 1是智能体才会采取对应行动。

世界状态智能体状态
Mineral 当前矿物储量Hunger 智能体饱腹值
Build 已建造建筑
BuildWaiting 待建造建筑
MineWaiting 待开采矿物

实验预期

  1. 当增加待建建筑时,在没有足够矿物且没有待开采矿物时,智能体不会行动。
  2. 在上述情况下,增加待开采矿物直到>2,智能体应当在开采2个矿物后自行完成建造任务。
  3. 在上述情况下,在上述情况下,当饱腹值<20,智能体应当去餐区进食,随后回来继续完成上述任务。

实验结论

通过点击对应的Cube可以增加待开采矿物和待建造建筑。

GOAP实验DEMO

基本符合预期。

有一段进食结束之后,矿物还剩2个,但是没有直接去建造,而是又去挖了一个矿之后才去建造,看起来是个Bug,后续再研究一下。

小结

基本实现了基于GOAP的单智能体行为,后续继续探索HTN的多智能体管理,以及尝试优化现有的GOAP实现,让智能体的配置和行为开发变得更简便些。

UnityGOAP(Goal-Oriented Action Planning)设计中,Goal(目标)是AI决策过程中的终点,代表了AI当前想要达成的最终状态或条件。设计Goal时需要考虑的是,它应该是清晰且可达成的,并且需要定义完成目标后会产生的正面效用(Utility)。每一个Goal都应当包含至少一个条件,该条件是AI执行一系列动作(Action)后能够达成的。 设计Goal时,你可以遵循以下步骤: 1. 明确Goal的条件:确定什么情况下该Goal被视为完成。 2. 设定Goal的效用值(Utility):用于比较不同Goal的重要性。 3. 考虑Goal的前置条件:可能存在需要达成的其他Goal或条件,作为当前Goal的前提。 4. 目标优先级:根据游戏设计需求,设置不同Goal的优先级。 案例展示: 假设我们正在设计一个游戏中的NPC(非玩家角色),它需要收集资源来建造一个避难所。我们可以为这个NPC设计一个“收集资源”Goal,该Goal的条件可能是“拥有至少5个木头和3个石头”。 Goal设计如下: ```csharp public class CollectResourcesGoal : Goal { public const string GOAL_NAME = "CollectResources"; public CollectResourcesGoal() { Name = GOAL_NAME; AddPrecondition("HasWood", 5); // 前置条件:拥有至少5个木头 AddPrecondition("HasStone", 3); // 前置条件:拥有至少3个石头 AddEffect("IsResourceCollected", 1); // 完成条件后,设置资源收集完毕的标志 } public override float CalculateCost(Agent agent) { // 计算达成目标的成本,这里简化为距离避难所的直线距离 float distanceToBase = Vector3.Distance(agent.transform.position, agent.home.transform.position); return distanceToBase; } public override bool Verify preconditionCheck, Effect achieved { // 验证前置条件是否满足和效应是否实现,这里简化为资源数量检查 return agent.HasResource("Wood", 5) && agent.HasResource("Stone", 3); } } ``` 在上述案例中,NPC需要收集资源以建造避难所,因此定义了“CollectResources”Goal,这个Goal要求前置条件是拥有至少5个木头和3个石头,并且完成这个Goal会增加“IsResourceCollected”效应。这个效应可以被其他Goal使用,作为它们的前置条件。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值