lyh916

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

参考链接:

https://www.cnblogs.com/01zxs/p/9863715.html

https://blog.csdn.net/AcmHonor/article/details/123234763

https://blog.csdn.net/u012632851/article/details/89647097?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-89647097-blog-82943972.pc_relevant_3mothn_strategy_and_data_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-89647097-blog-82943972.pc_relevant_3mothn_strategy_and_data_recovery&utm_relevant_index=3

https://blog.csdn.net/wuming2016/article/details/116858357

 

BehaviorDesigner下载

https://gitcode.net/linxinfa/unitybehaviordesigner

 

一.制作一颗简单的行为树

如下,是一颗简单的怪物行为树,当看见主角时,向主角移动;否则保持站立状态

AICanSeeObj.cs

 1 using BehaviorDesigner.Runtime;
 2 using BehaviorDesigner.Runtime.Tasks;
 3 using UnityEngine;
 4 
 5 public class AICanSeeObj : Conditional
 6 {
 7     public float distance = 2f;
 8     public SharedTransform target;
 9 
10     public override TaskStatus OnUpdate()
11     {
12         if (Vector3.Distance(transform.position, target.Value.position) < distance)
13         {
14             return TaskStatus.Success;
15         }
16         else
17         {
18             return TaskStatus.Failure;
19         }
20     }
21 }

AIMoveTo.cs

 1 using BehaviorDesigner.Runtime;
 2 using BehaviorDesigner.Runtime.Tasks;
 3 using UnityEngine;
 4 
 5 //移动到指定的目标
 6 public class AIMoveTo : Action
 7 {
 8     public float speed = 1f;
 9     public SharedTransform target;
10 
11     public override TaskStatus OnUpdate()
12     {
13         if (Vector3.Distance(transform.position, target.Value.position) < 0.1f)
14         {
15             return TaskStatus.Success;
16         }
17         transform.position = Vector3.MoveTowards(transform.position, target.Value.position, speed * Time.deltaTime);
18         return TaskStatus.Running;
19     }
20 }

AIIdle.cs

1 using BehaviorDesigner.Runtime.Tasks;
2 
3 public class AIIdle : Action
4 {
5     public override TaskStatus OnUpdate()
6     {
7         return TaskStatus.Running;
8     }
9 }

 

二.行为树的特点以及中断机制

在行为树中,一般一个节点返回Success或者Failure后,这个节点就不会再执行了(除非行为树重新执行或者该节点在Repeater节点下)

如下,白色是主角,红色是怪物,一开始两者距离较远,怪物处于Idle状态,即使后面拉近距离,AIIdle也不会被打断,不符合我们设定的AI逻辑(距离较近时向主角移动)

行为树的中断机制是通过设置组合节点的AbortType来实现的

None:不打断

Self:打断该组合节点下方的节点,如下,左上方有个"向下"的标记

Lower Priority:打断该组合节点右方(低优先级)的节点,如下,左上方有个"向右"的标记。一般来说,行为树是从上到下,从左到右执行的,左侧的节点优先级较高,右侧的节点优先级较低,所以低优先级指的是右方

Both:Self + Lower Priority的结合,如下,左上方有个"向下向右"的标记

中断机制:当给组合节点设置中断后(Self/Lower Priority/Both),行为树会(每帧)检测该组合节点已执行过的子条件节点,如果条件节点的状态发生变化,就会中断当前正在执行的Running节点,转而执行该条件节点

 

三.应用

1.设置中断为Lower Priority,运行游戏,一开始距离较远,所以一直在运行AIIdle节点

拉近距离后,AIIdle节点被打断,转而执行AICanSeeObj和AIMoveTo

 

2.上面的例子有个问题,就是进入AIMoveTo节点后,即使后面拉大距离,AIMoveTo节点也不会被打断

解决方法就是,设置中断为Both,这样Sequence节点下方的AIMoveTo和右方的AIIdle都能被打断了

posted on 2023-01-08 17:42  艰苦奋斗中  阅读(648)  评论(0编辑  收藏  举报