最近项目增加大量的怪物AI,涉及到一些持续性的动作(跑向目标点、追击敌人等),之前的AI虽然是用行为树的想法做的,但对于持续动作状态的终止都是通过在代码中加条件判断实现的。所以不能达到“写好条件、动作,其他的让策划来”的目的。所以觉得需要改进一下~ 这里对整个过程的思考做下记录,有些地方也还没有想明白。
关于节点划分
瞬间动作节点
定义:主要是完成一些瞬间动作,整个动作过程是瞬间完成。例如,选择一个仇恨目标。 执行返回:success,failure
持续动作节点
定义:与瞬间动作相对,整个动作过程需要经历持续一段时间。例如,跑到某一点。 执行返回:success,running,failure
持续动作节点需要包含:进入节点的逻辑、loop中节点Running的处理逻辑、节点终止的逻辑。
前置条件(终止条件)
定义:跳出当前节点Running状态的条件,可以是满足条件退出(终止条件)也可以是满足条件继续执行(前置条件)。
关于持续性动作节点的Enter逻辑
进入节点的逻辑主要是开始执行一个行为,可能返回失败(如:寻路失败),或者running,如果返回running则保存AI当前Running的持续动作节点以及其终止条件列表。如果返回失败则可以根据需要做出处理(可以是忽略这个行为继续执行后续的节点,或者进行失败后的特殊逻辑)。
关于持续动作节点的Running状态
在AI行为中有时一个状态会持续很久,如果没有running,AI会继续从行为树的根节点开始遍历,但最终仍然会继续执行之前执行过得动作,在这个过程中如果存在计算量很大的条件判断就会浪费系统资源。所以引入了running状态,如果一个AI一直处于某个行为的running状态下,只需要判断这个行为的前置条件(终止条件),如果可以继续则直接执行该行为节点的Running逻辑,否则执行节点终止逻辑。
关于持续动作节点的Exit逻辑
如果AI对象上存在当前Running的持续动作节点,则在每次Loop进入Running之前对前置条件(终止条件)进行判断,如果满足退出节点的条件,则执行Exit逻辑。
Exit逻辑主要是做一些信息的设置和清除,例如,无路客套(逃跑寻路失败)则反击敌人(需要设置攻击目标),目标死亡退出反击(清空攻击目标)。同时需要清空AI对象上当前Running信息。
一些未验证的想法:
- 在因为条件列表中的条件终止时会有不同的终止事件触发。
- 对于不同条件造成的终止进行不同的处理,并返回failiure或者success。