Behavior Creator 行为树可视化编辑器

  • 这是一款为 CocosCreator 深度定制的行为树可视化编辑器插件
  • 已实现 SelectorSequenceParallel 三种组合节点
  • 已实现 ConditionalDecorator 两种装饰器
  • 已实现 Service 服务类型
  • 已实现 Task 任务类型
  • 支持自定义节点注册到行为树编辑器
  • 支持类属性差异化更新
  • 支持节点生命周期 onEnableonUpdateonDisable 等通用事件委托

注意

  • 仅支持在 CocosCreator v3.3.0 及以上版本中使用
  • 本插件的实现综合参考UE行为树和Unity行为树Behavior Designer

效果预览

example-2022-04-27-1

快速开始

  • CocosCreator 编辑器菜单 扩展 --> 商城 中搜索 BehaviorCreator 即可找到该插件,购买后下载到本地

  • 导入插件 oreo-behavior-creator 并启用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wg4KY3dI-1651722100844)

  • 资源管理器 面板中看到 oreo-behavior-creator 运行时 已载入,则表示插件导入成功

    image-20220427173208187

  • 注意,因插件需要导入运行时脚本,在CocosCreator编辑器已打开状态下可能会出现以下错误,此时需要重启编辑器

    image-20220427175405403

插件入口

  • 行为树编辑器是由 json 数据驱动的,其入口已集成到 BehaviorTree 组件的属性检查器面板,可通过以下方式启动

    1. 新建空节点,在节点上挂载 BehaviorTree 组件

      examples-2022042701

    2. 新建内容为空{}json资源,并关联到 BehaviorTreeJsonAsset 属性。点击 Edit Behavior 即可打开行为树编辑器

      examples-2022042702

加载示例

  • 在运行时目录extensions\oreo-behavior-creator\runtime\examples\data 中提供了一些简单示例,可以通过 Load 菜单加载到行为树编辑区,Save 保存后下一步运行查看效果。

    (img-6OSro9Dv-1651722100851)

运行效果

  • BehaviorTree 组件默认是没有启用 LogTaskChanges 属性的,我们先勾选以便在控制台输出 log。

    examples-2022042704

    注:当行为树某次执行结果不是 Running 状态时,本次运行结束。如果需要重新开始,需要勾选 RestartWhenComplete

示例分析

  • 我们通过分解行为树并编写代码逻辑,一步步实现以下效果

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KnZZ9tYc-1651722242437)

巡逻行为分析

  • 我们设定一次巡逻主要包括以下逻辑

    1. 在指定区域目标点之间来回移动

      通用 Task 任务节点

    2. 到达指定点后原地休息等待一段时间

      Wait 任务节点

  • 由于上述是一个连续有序的行为,因此需要将它们挂载到 Sequence 父节点

    Sequence 序列节点

  • 整体巡逻行为如图所示

    examples-2022042705

场景搭建

  • 如图所示,我们在场景中添加了一个 AIEnemy 敌人 AI 以及三个巡逻目标点

    image-20220427223626942

代码逻辑

  • 随机移动

    在巡逻行为树结构中,随机移动 节点是一个通用 Task 任务节点,需要我们定制 onUpdate 任务更新逻辑。

    image-20220427231352792

    新建 AIEnemy.ts 组件类并实现找点随机移动逻辑,挂载到 AIEnemy 场景节点上。主要逻辑包含两点:

    1、到达目标点时返回 Success 表示成功,由父节点 Sequence 顺序执行下一个子节点的行为,即 原地休息

    2、未到达目标点时返回 Running 表示任务还在持续,由父节点 Sequence 下一次 tick 继续执行

    具体实现如下:

    onRandomMove(){
        this._playAnim("run", 1);
    
        //这里为了方便,只是按点索引顺序移动
        let point = this.patrolPoints[this._index];
        //自身点位置
        pos1.set(this.target.position);
        //目标点位置
        pos2.set(point.position);
    	//朝向
        this.target.lookAt(pos2);
    
        //目标点达标与否阈值判断
        if(Vec3.distance(pos1, pos2) < 0.1){
            this._index++;
            if(this._index>=this.patrolPoints.length){
                this._index = 0;
            }
    
            this._playAnim("idle");
            //到达目标点时返回成功,由父节点 `Sequence` 顺序执行下一个子节点的行为,即 `原地休息`
            return bt.BehaviorStatus.Success;
        }
        else{
            let pos = this.lerp(out, pos1, pos2, 0.02);
            this.target.setPosition(pos);  
    
    		//未到达目标点时返回 Running ,由父节点 `Sequence` 下一次 tick 继续执行
            return bt.BehaviorStatus.Running;  
        }
    }
    
  • 原地休息

    这是一个内置 Wait 任务节点,主要作用就是在指定时间内任务直接返回 Running 状态,表示任务还在持续,时间到达后返回 Success 表示任务完成。

    Wait 任务有一个 duration 属性,表示任务持续时间。这是一个 SharedVariable 共享变量属性,与Blackboard黑板变量关联。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P04OUUdS-1651722276518)

逻辑绑定

  • 我们先来指定 原地休息 时间

    新建一个 SharedNumber 数字类型的黑板共享变量,值设定为 2,并指定给 duration 属性,表示原地休息 2 秒

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IbeyKN8C-1651722100861)(https://www.exporter.top/behavior/zh-cn/example/img/examples-2022042706.gif)]

  • 绑定 随机移动 任务的 onUpdate 委托逻辑。

    examples-2022042707

    如图,将 onUpdate 逻辑绑定到 AIEnemy 组件的 onRandomMove 方法

    Delegate 委托逻辑绑定与 CocosCreator 内置按钮事件绑定过程相似

运行效果

  • 首次运行效果如下

    examples-2022042708

  • 我们发现AI 移动到指定目标点且原地休息结束后,并没有继续移动到下一个目标点。这是因为,对于本次行为来说,Wait 执行结束并返回 Success 状态,表示行为树已经全部执行完毕。如果需要重新开始,只需勾选 BehaviorTree 组件上的 RestartWhenComplete

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pUTMyYNr-1651722100866)

  • 最终效果如下

    examples-2022042709

追逐行为分析

  • 我们设定一次追逐主要包括以下逻辑

    1. 当玩家出现在 AIEnemy 的感应区域内时,AIEnemy 立即移动并靠近玩家

      通用 Task 任务节点

    2. 当玩家被追逐达到受击范围时,AIEnemy 发动一次攻击。我们设定一次攻击包含实际攻击和技能CD两个任务。

      Sequence 序列节点,通用 Task 任务节点、Wait 任务节点

  • 由于靠近一次攻击 是区分条件执行(不在受击范围就靠近,在受在范围就攻击),即一次只会执行一个分支,因此需要将它们挂载到 Selector 父节点

    Selector 序列节点

  • 此时追逐玩家行为如图所示

    image-20220427223046545

场景搭建

  • 如图所示,我们在上一个场景的基础上添加了一个 AIPlayer 节点表示当前玩家

    image-20220427231323448

代码逻辑

  • 靠近

    靠近 节点也是一个通用 Task 任务节点,需要我们定制 onUpdate 任务更新逻辑。

    更新 AIEnemy.ts 组件类并实现相关逻辑。主要逻辑包含:

    1、判断玩家是否在受击范围内

    2、不在范围内则靠近

    3、在范围内则攻击

    范围判断:

    canAttack(){
        //当前位置
        pos1.set(this.target.position);
        //玩家位置
        pos2.set(this.player.position);
    
        //受击范围判断
        if(Vec3.distance(pos1, pos2) < 1){
            return bt.BehaviorStatus.Success;
        }
    
        return bt.BehaviorStatus.Failure;
    }
    

    移动到攻击范围

    onMoveToAttack(){
        if(this.canAttack()==bt.BehaviorStatus.Success){
            return bt.BehaviorStatus.Failure;
        }
        else{
            pos1.set(this.target.position);
            pos2.set(this.player.position);
            this.target.lookAt(pos2);
    
            let pos = this.lerp(out, pos1, pos2, 0.03);
            this.target.setPosition(pos);
    
            this._playAnim("runHit");
            return bt.BehaviorStatus.Running;
        }
    }
    

    发动攻击

    onAttack(){
        this._playAnim("attackLeft");
        //一次攻击结束后等待技能冷却,所以在攻击动作结束后播放防御动画 'fightIdel'
        this.anim.once(AnimationComponent.EventType.LASTFRAME, ()=>{
            this._playAnim("fightIdle");
        })
        //主角受击
        this.aiPlayer.beAttacked();
        return bt.BehaviorStatus.Success;
    }
    

    技能CD

    这也是一个内置 Wait 任务节点,与上一节中 巡逻 行为的 原地休息 节点类似,只需指定持续时间 duration 即可

    image-20220427232557255

逻辑绑定

  • 分别绑定 靠近攻击 任务的 onUpdate 委托逻辑。

    image-20220427233042108

    image-20220427233106676

  • 本次运行效果如下

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hbigpPIt-1651722100874)

    我们看到,AI 启动后立即向玩家靠近,这不太科学。我们给 AI 添加一个感应区域作为 AI 的视野,当玩家出现在感应区域范围内时 AI 才奔向玩家。

    1. 我们使用内置的 Conditional 条件元素来实现条件判断

    2. 视野判断代码实现

      onHasSight(){
          //当前位置
          pos1.set(this.target.position);
          //玩家位置
          pos2.set(this.player.position);
      
          //视野范围
          if(Vec3.distance(pos1, pos2) < 8){
              return bt.BehaviorStatus.Success;
          }
      
          return bt.BehaviorStatus.Failure;
      }
      
    3. 绑定 onUpdate 逻辑

      image-20220427235135835

运行效果

  • 增加视野判断后,运行效果如下

    examples-2022042711

    圆形区域为 AI 视野,当玩家进入视野时,AI 开始追逐,当追逐到玩家受击范围时,展开攻击。

下一步

加入

  • BehaviorCreator QQ交流群:
  • 659064495

说明

  • 压缩包内包含完整运行时源码以及示例项目工程,详见包内 Readme.md 文档
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值