数据结构论坛

首页 » 分类 » 定义 » npc的AI是如何运作的从程序到策划深入
TUhjnbcbe - 2025/6/3 12:40:00
白癜风诊疗规范 https://disease.39.net/bjzkbdfyy/180102/5972951.html

文/猴与花果山

在我们玩的大多游戏中,总有这么一些角色默默无闻的陪伴着我们,这就是游戏中的npc。npc本意是non-playercharacter,即游戏中非玩家操作的角色都是npc,包括怪物、村民等等元素都是npc。而“操作”着这些npc来陪我们进行游戏的,正是游戏AI。因此游戏AI的设计开发,是大多游戏中极为重要的一环。

(王者荣耀中的小兵,就是由游戏AI操作着的npc角色)

01npc的AI是如何运作的?

通常我们都认为“行为树”、“状态机”组成了游戏AI,也有把GOAP(目标导向型行动计划)当做是游戏AI设计的,其实这样的概念是不对的。npc的AI是这样运行的:

就像现实中的我们思考问题一样,在游戏的每一帧(游戏运行的最小时间单位),npc们都会这么思考——首先,“我”(这个npc)有什么事情要做吗?拿出“小本子”看看工作计划,如果有事情要做,就会明确一个todoThing(现在要干什么)。有了todoThing就会仔细想一想,这个todoThing能做的成吗?因为“计划赶不上变化”,有些原本计划好可以做的事情,现在可能因为环境(circumstance)发生了变化,以至于无法进行了:

当无法进行或者原本就没有todoThing的时候,npc就会开始思考“我现在要干啥”。这里就是我们常见的“行为树”发挥作用的地方,但是不论是“行为树”、“蓝图”,实际上返回的都是一段数据,并且被记录到“小本子”里作为工作计划,然后重新开始看是否可以执行这个计划,最终开始执行具体行动。

所以“把想要做什么写进小本子”,才是AI的核心,而“行为树”只是写入“写入小本子”的“写法”之一,包括脚本代码(如Lua)、UE4的蓝图等都是“写小本子的写法”。“写小本子”这件事情得有思路,不管是蓝图还是行为树都是把设计师的思路“写进去”的过程,而GOAP提供的是一种设计游戏AI内容的思路。行为树和GOAP,只是游戏AI中最核心的一环的数据录入的思路和方式之一,因此行为树和GOAP都不等于游戏AI。

下面是代码时间

首先我们需要有一个关于角色状态的东西,它也会返回当前角色是否可以执行AI(本文所有图片的伪代码使用TypeScript):

exportclassCharacterState{

publicvalue:number=0;

//这里用于返回是否能执行AI

publicCanRunAI():boolean{

return(1this.value)==0;//可以设计更多状态不能执行AI

}

publicstaticSTATE_STUN=1;

publicstaticSTATE_POISONED=11;

publicstaticSTATE_CONFUSED=12;

//...这里可以根据游戏设计来定义更多状态

}

接着就是角色对象,在角色对象中,有一些内容是设计师需要设计的:

exportclassCharacter{

//npc必然是属于角色类的,只是某些属性的值和玩家的不同而已

//此处省略AI无关的其他数据

privatetodoThing:Object;//这就是“小本子”

privatestate:CharacterState;

privateteamId:number=0;

//这里正是策划设计的重要部分,也是AI的大脑

privateWhatToDo():Object{

letres={}//Unity推荐的做法在这里是行为树

//这里开始则是这个角色的AI执行内容

//如果你大多是ifelse,那就跟行为树没区别了,顶多执行效率高些

returnres;

}

//这个函数是图中的“3T.想一想执行细节”

privateCanDoBehave():boolean{

if(!this.todoThing)returnfalse;

return(

//这里正是策划需要设计规则的地方

//这里的内容多和少都不坏,取决于游戏规则的复杂度

//但是如果这里依赖了其他对象,依赖的越多,设计越蹩脚。

false

);

}

//这正是AI的核心流程,也是每一帧执行的内容

publicFixedUpdate(){

if(true==this.state.CanRunAI()){

if(

!this.todoThing

//2F.如果“小本子”没东西

false==this.CanDoBehave()//3T.如果“小本子”的事情做不了

){

this.todoThing=this.WhatToDo();//执行AI

}

//接下来当然是具体怎么执行AI的问题了。

}

}

}

可见,“行为树”在整个AI中,是完全可以被其他方法取代的内容。

02“群体AI”是究竟怎么回事儿?

当一个游戏AI进行“思考”,也就是准备小本子的时候,除了会参考一些自身状态,还会参考一块“小黑板”内的信息。这块“小黑板”的信息,游戏的其他系统也会写入一些必要的数据,以帮助游戏AI更好的明确自己该做什么。

这小黑板上的数据,包括两种类型的:

游戏全局的一些状态:比如游戏如果有天气,那么现在是什么天气?可能NPC会需要因为下雨天,所以找房子躲起来,或者撑起伞。这些数据都是随着游戏推进,数据发生变化的时候会改写的数据,对于游戏AI而言,是只读数据。当然尽管我们举例只说了天气,但是通常情况下,游戏进程中的所有变量都应该被写在小黑板里,供NPC的AI获取信息。一些“命令”:在这个小黑板当中,也会记录一些由其他系统,比如玩家操作系统带来的命令。比如“1组去A区”就是一种命令,当NPC在思考AI的时候,会发现有一条“1组去A区”的命令,此时如果这个NPC发现自己是1组的,他就会去A区。当然,信息只是用来参考的,“不听话”的1组队员,完全是可以无视这条指令的。

我们注意到了,在“小黑板”上有一些“命令”,这个“命令”正是很多游戏中“群体AI”的核心关键所在。比如在即时战略中,玩家操作一个小队的角色移动到某个地方,就是一个“群体AI”;

(即时战略中,玩家控制一个小队保持队形驶向某处,就是一个“群体AI”)

除了玩家操作的,还有游戏中场景里刷了多个敌人,敌人与敌人之间像小组一样的协作作战;还有足球类游戏中球员之间的跑位、配合等,都是典型的“群体AI”。

(在FIFA20等足球游戏中,球员有组织的行动也是一种“群体AI”)

而“群体AI”的发起者,未必来自于一个更高级的系统(通常被认为是“游戏AI系统”),因为这个“命令”对于执行游戏AI的npc来说不是只读的数据,所以也可以由一个npc的AI发起。

但是不论是谁发起的,都应该是在列表里新增一条,而不是轻易修改已经存在的数据,当游戏运行了一定帧数之后,自动清除掉,因此每一条“命令”必不可少的数据是“持续时间”。

(即使已经有的条目,也不能“修改”而只能“新增”,因为采纳不采纳的判断,是由游戏AI根据这些信息“思考”出来的,我们只提供信息,不提供解决方案)

因此,当我们看到游戏中角色有序的群体执行某件事情的时候,通常是通过这种方式来发起“群体AI”,然后每个npc独自行动的时候恰好形成了步调一致的结果,实际上他们之间互相并没有任何“沟通”。

下面是代码时间

先是本章的主角——小黑板:

//这是小黑板上的

1
查看完整版本: npc的AI是如何运作的从程序到策划深入