Behavior Designer行为树
行为树就是将所有可能发生的状态进行模块化,将状态抽象成一个个的行为,然后在每个行为之间可以增加一些节点
复合节点(Composites Node)进行每个节点之间逻辑控制,
装饰节点(Decorator Node)进行子节点状态的控制,
行为节点(Action Node)进行具体行为的处理,
条件节点(Conditionals Node)用于判断该条件是否成立等。
Composites
常用的复合节点有:
1)sequence:
序列节点
子节点顺序执行,当其中一个失败,返回失败
子任务其中有一个执行失败了,则不会往下执行了
所有任务执行成功,才返回成功
idle:一直返回running
wait: 等待一段时间后返回成功
Restart When cor 当结束后重启
2)selector
并发选择节点,子节点并行,
只要其中一个子节点成功了,就返回成功,
其他子节点不再执行
常用节点:
Flee: 远离
TargetTransform:目标
Fleed Distance: 逃跑到离目标多少距离为成功(如果目标的视野是7,则需要跑到8为成功)
LookAheadDistance:先跑多少米再做判断
Patrol :
巡逻
添加 Behavior Designer Movement 扩展包
1)创建,设置速度speed,角速度,距离多少Distance(默认0.1)为到达了点
2)场景静态,烘焙,给选中的对象添加NavMeshAgent组件
Seek
寻找某个点 ,使用Unity NavMesh
移动到这个点
Variables : 变量
变量可以直接给节点传值,也可以通过节点给变量赋值
Can See Object :
是否看到某个对象
Object LayerMask 指定层的目标
Filed of view Anle 视野角度
View Ditance 视野距离
Object In Sight : 将看到的Object位置给变量Target赋值
Abort Type
中止类型
1 ) Onoe 子节点的条件判定,只判定一次
2 ) Self 条件判断不成功,中止条件自身同父类的子节点
当子节点判定条件不满足时,打断自身的任务
当执行优先级别低的节点时,会持续判断子节点设置的条件
( 当不再看到主角时,打断自身seek,开始执行右边的任务seek)
3 ) LowerPriorty,条件判断成功,中止优先级低的
当条件满足时,打断右边的节点,执行子节点
当看到主角时,打断Sequence右边节点,
开始执行追的节点,直到追到为止,并不会从 新判断)
4)Both 两者都会中断
手写一个Seek
SharedFloat:共享的变量
using System.Collections; using System.Collections.Generic; using UnityEngine; using BehaviorDesigner.Runtime; using BehaviorDesigner.Runtime.Tasks; //引入命名空间 public class MySeek : Action { public SharedFloat Speed = 0; //按照Seek格式定义公开的变量,速度 public SharedFloat ArriveDistance = 0.1f; //距离,判定多少为到达目标 public SharedTransform tagert; //目标位置 public override void OnAwake() { } public override TaskStatus OnUpdate() { if (tagert == null||tagert.Value==null) //如果目标为空 { return TaskStatus.Failure; //返回失败 } transform.LookAt(tagert.Value.position); //看向目标 //向目标移动 transform.position = Vector3.MoveTowards(transform.position, tagert.Value.position, Speed.Value * Time.deltaTime); //如果与目标距离的平方,小于设定值的距离 if (Vector3.Distance(tagert.Value.position, transform.position) < ArriveDistance.Value) { return TaskStatus.Success; //则到达目标,返回成功 } return TaskStatus.Running; //否者反正运行,继续执行方法 } }
手写一个Can See Object 脚本:
public SharedTransform target; //共享目标
using BehaviorDesigner.Runtime.Tasks; //命名空间 using System.Collections; using System.Collections.Generic; using UnityEngine; using BehaviorDesigner.Runtime; //命名空间 public class MyCanSeeObject : Conditional { public Transform[] Objects; //看到的目标 public SharedFloat FiedOfViewAngle = 90; //视野角度 public SharedFloat ViewDistance = 7; //视野长度 public SharedTransform target; //共享目标 public override TaskStatus OnUpdate() { if (Objects==null) { return TaskStatus.Failure; //数组为空,返回失败 } foreach (var item in Objects) //遍历数组 { float distance = Vector3.Distance(transform.position, item.position); //计算目标与自身的距离, float angle = Vector3.Angle(transform.forward, item.position - transform.position); //计算目标与自身正前方的角度 this.target.Value = item; //共享这个目标 if (distance<ViewDistance.Value&&angle<FiedOfViewAngle.Value/2) //如果距离小于视野距离,并且角度小于视野角度的一半 { return TaskStatus.Success; //返回成功 } } return TaskStatus.Failure; //否者返回失败 } }
Decorator节点:
针对单个节点做操作
Inverter:将节点的结果反转