Unity Behavior Designer学习笔记与工作总结

为什么要用Behavior Designer

日常工作中,我们总要用代码实现各种各样的AI,例如怪物攻击玩家角色,通常情况下有三个阶段,Idle(原地挂机,通常与玩家离的较远的情况),WalkOrRun(与玩家到一定距离,开始追寻玩家),Attack(到达一定距离开始攻击玩家)。
通常情况下我们会使用状态机去实现上述功能,但是当情况较多,实现起来较为复杂,因此我们可以使用Behavior Designer插件,由这个插件带你去控制。说白了就是别人封装好了一个脚本,你只要填入相对应的参数,就可以实现状态机的控制效果。

实现一个最简单的Behavior Designer


如上图所示,选中一个Cube,然后再Tool打开Behavior Designer,在行为树面板中右键添加行为树,然后增加一个Action(行为,具体做什么)Log,运行即可看到输出了我们在Inspector面板中的信息。

Behavior Designer的属性介绍

介绍一下面板中的属性:

Behavior

在这里插入图片描述
Behavior:该行为树的一些设置,根据自己项目中需要进行设置。

Tasks

在这里插入图片描述
Composites:复合使用,代表当前节点有多个行为复合,常用的是Selector(实现Or的效果,多个行为节点中只使用其中一个),Sequence(实现队列效果,挨个挨个执行,如果其中有行为返回了false,那么则直接结束)。
目前我常用的是上述两个,后续有案例详细讲解。
Decorators:装饰节点,可以对单个节点进行装饰,例如翻转,希望获取是否的效果,那么则继续进行。Inverter。没怎么用过,此处暂不介绍,后续如果用到会进一步补充。
Actions:行为节点,即具体干什么内容,例如Log。
Conditionals:判断节点,判断是否满足条件,可以与Sequence配合起来使用,如果满足条件则执行后续内容,不满足条件则直接退出当前状态。

Variables

变量值,此处可以添加当前行为树下一些共用的值(引用类型),后面会详细讲解。

Inspector

属性设置,和unity自带的一样,此处不再过多讲解。

案例1:实现最简单的怪物巡逻效果

此处我们假设Cube为敌人,只需在Cube上添加上一个行为树,然后添加Action下的Patrol,然后设置一下Patrol的参数,即可实现。
ps:行为树插件依赖Unity的Nav导航系统,因此需要将Plane设置为Nav静态,然后给Cube添加上NavMeshAgent组件即可。
在这里插入图片描述
我们可以看到Patrol为绿色,代表它一直在执行

案例2:怪物在巡逻,玩家向目标点走去,如果路上看见了怪物,那么则改为追怪物。

要完成上述这个要求,我们需要用到一个Selector(判断玩家是去往目标点走去,还是追寻怪物,二选一),一个Sequence(用来判断是否发现了怪物,发现了则追击),两个Action下的Seek(用处是去往目标点,一个是去往最初设定的目标点,一个是去往怪物的目标点),一个Conditionals下的Can See Object,判断是否发现了目标。
详细步骤如下图所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如图所示:最初Can See Object一直是叉,但是有一个红圈,代表它一直在检测,此处就是因为我们将Sequence中的Type改为Lower Priotity,左边权重比右边高,则会打断右边。
Abort模式还有Self和 Both。
Self代表可以打断自身。例如最初检测到了怪物,玩家追寻怪物,但是玩家速度比怪物慢,因此没追上,脱离了视野,那么此时不满足Can See的条件,就会打断,而向最初设定的目标点走去。
Both代表同时执行Self和Lower Priotity。
此处不在演示,感兴趣的小伙伴可以自己试一下。
Demo案例

不同行为树之间的切换

实际项目中,一个物体可能有多种不同的状态,不同的状态下行为有些许差异,我们虽然可以写成一个行为树(想想就好复杂),因此,行为树插件支持一个物体拥有多个行为树,但是同时只能运行一个。
下面拿一个简单的Demo举例。
一个员工,需要从A点到达B点工作,A点是家,B点是工厂。
逻辑为 员工从A点出发,跑向工厂,到达工厂工作一段时间后跑回家。
员工可能今天干的活是修瓷砖,明天是砌墙,俩者之间仅仅有此不同,因此我们就可以创造两个行为树,只对这个动画做区分。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

public class AniTest : MonoBehaviour
{
    Animator animator;
    public Transform objPosition;
    public List<BehaviorTree> FirestS = new List<BehaviorTree>();
    public List<BehaviorTree> Seconds = new List<BehaviorTree>();
    private void Awake()
    {
        animator = GetComponent<Animator>();
        BehaviorTree[] trees= FindObjectsOfType<BehaviorTree>();
        foreach (var item in trees)
        {
            if(item.Group == 1)
            {
                FirestS.Add(item);
            }
            else
            {
                Seconds.Add(item);
            }
        }
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.H))
        {
            foreach (var item in Seconds)
            {
                item.DisableBehavior();
            }
            foreach (var item in FirestS)
            {
                item.EnableBehavior();
            }
        }

        if (Input.GetKeyDown(KeyCode.J))
        {
            foreach (var item in FirestS)
            {
                item.DisableBehavior();
            }
            foreach (var item in Seconds)
            {
                item.EnableBehavior();
            }
        }
    }

    void EventTest()
    {
        Debug.Log("执行了动画事件");
    }
}

可以看到,First行为树最初是绿色,然后变成灰色,此时是因为我通过代码控制,切换到了另一个行为树Second,切换到那个行为树发现是绿色的。
并且做得也是Second的动作(挥手,First是散步)。
行为树插件的功能很强大,我目前了解到的只是冰山一角,还可以和动画系统中自带的事件系统起到意想不到的效果。控制行为树插件播放动画,动画播完之后可以执行一些事件。
在这里插入图片描述
此处其实是根据我实际工作项目经验改了一下,之前工作要控制工人运动,路程大差不差,缺的就是最后运行的动画。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值