Task
// bt.Task.ts
class Task;
Task
是所有任务的基类。
API
/**
* 全局唯一 UUID 。主要用于编辑器。
*/
public readonly uuid: string;
/**
* 任务的名字。
* @btprop 该属性在 behavior-dog 的属性检查器上可见
*/
public name: string;
日志
推荐使用内置的日志工具打印日志。他会自动为消息添加前缀标签,方便调试。
/**
* 通过 log.v/d/i/w/e(...args) 向控制台打印格式为
*
* [ behavior-dog ] [ 行为树名字<行为树UUID>.任务类名<任务名字> ] ...args
*
* 的日志。
*/
public readonly log: ILogger;
/**
* 日志开关只会影响到 log.v 。
* 当日志关闭时, log.v 不会输出日志,但 log.d log.i log.w 和 log.e 能照常输出。
*
* 通过 log.VERBOSE 的值可以判断日志开关是否打开。
*
* @btprop 该属性在 behavior-dog 的属性检查器上可见
*/
public enableLog: boolean;
行为树
获取当前行为树实例。
以下 2
个接口都返回当前行为树实例的引用。
/**
* 行为树实例。
*/
public readonly tree: IBehaviorTree;
/**
* 返回行为树实例。
*/
public getBehaviorTree<T extends IBehaviorTree>(): T;
根任务
/**
* 行为树的根任务。
* 入口 Entry 的子任务。
* 当前任务正好是根任务时,这个值为 null 。
*/
public readonly root: IBranchTask;
父任务
/**
* 父任务。
* 当前任务正好是根任务时,这个值为 null 。
*/
public readonly parent: IBranchTask;
/**
* 在父任务中的索引值。
*/
public readonly index: number;
权值
目前权值主要是用于 PriorityCompositeTask 的随机任务生成算法。
/**
* 任务的权值。
* @btprop 该属性在 behavior-dog 的属性检查器上可见
*/
public weight: number;
状态
每个任务在执行一次 tick
之后都会返回一个状态值,表示此次执行的结果。
该状态值通常为 onUpdate
生命周期函数 的返回值。
enum Status {
/**
* 失败。
*/
FAILURE = 0,
/**
* 成功。
*/
SUCCESS,
/**
* 运行中。
*/
RUNNING,
}
通过以下接口可以读取到当前任务的状态,
/**
* 任务的当前状态。
*/
public readonly status: Status;
/**
* 任务是否正在执行。
*/
public readonly running: boolean;
/**
* 任务是否正在执行。
*/
public readonly entered: boolean;
/**
* 任务是否执行完成。
*/
public readonly completed: boolean;
数据共享
/**
* 本地黑板。一块行为树内部使用的黑板,可在任务之间传递数据。
*/
public readonly blackboard: IBlackboard;
/**
* 全局黑板。一块全局共享的黑板,可在场景之间传递数据。
*/
public readonly globalboard: IBlackboard;
关于黑板的接口,请看 这里 。
推荐使用另一种数据共享的方式 SharedVariable 。
但是
SharedVariable
只支持tree
和scene
2
个作用域。也就是说,他只能最多做到在同场景中的行为树之间共享数据。如果要在场景之间传递数据,只能使用全局黑板
globalboard
。
事件系统
行为树内置了一个事件系统,可以在任务之间传递事件。
/**
* 向一个任务发射事件。这个事件不会进行冒泡或广播,只有该任务的监听器能接收到。
* 1. 通过 on 注册的回调。
* 2. 该任务的 onEvent 方法。
*/
public fire(type: string, arg1?: any, arg2?: any, arg3?: any): boolean | void;
/**
* 向一个任务发射事件,并逐级向上传递,父任务的父任务都可以接收此事件,
* 直到其中一个任务的 onEvent 方法返回 true 或者没有父任务为止。
* 俗称冒泡事件。
* 返回 true 表明事件传递被中止。
*/
public emit(type: string, arg1?: any, arg2?: any, arg3?: any): boolean | void;
响应事件
/**
* 向一个任务注册事件回调,监听该任务上触发的事件。
*/
public on(type: string, cb: TaskEventCallback, target?: object): void;
/**
* 向一个任务注销事件回调。
*/
public off(type: string, cb: TaskEventCallback, target?: object): void;
事件回调函数的定义如下:
/**
* @param task 触发事件的 task
* @param type 事件的类型
* @param arg1 事件的第 1 个可选参数
* @param arg2 事件的第 2 个可选参数
* @param arg3 事件的第 3 个可选参数
*/
type TaskEventCallback = (task: ITask, type: string, arg1?: any, arg2?: any, arg3?: any) => void;
除了 on
方法注册事件回调之外, Task
脚本本身可以通过实现事件处理函数 onEvent
来响应事件。与 on
方法不同的是, 脚本中的事件处理函数可以阻止事件的传递,而事件回调不行。
/**
* 收到一个事件。这个事件可能是冒泡,也可能是广播,也可能两者都不是。
* 返回 true ,可以阻止事件的传递。
* 返回 false 或不返回,表明事件可以继续按他原来的规则传递。
*/
protected onEvent?(type: string, arg1?: any, arg2?: any, arg3?: any): boolean | void
/**
* 此方法在 onEvent 方法之前调用,可起到过滤事件的作用,但不会阻止事件在行为树中的传递。
* 返回 true ,继续调用 onEvent 方法。
* 返回 false ,不会调用 onEvent 方法,事件将继续按原来的规则向上或向下传递。
*/
protected onEventFilter?(type: string, arg1?: any, arg2?: any, arg3?: any): boolean;
手动执行
在行为树中,任务的执行时机由父任务决定,并不需要手动控制。
但某些情况下,需要对任务进行手动评估。比如前置条件任务 PreCondition 会在执行子任务之前评估一个条件任务,评估通过才会执行子任务。
为了满足这类需求,提供了下面这个接口,
/**
* 评估任务。
* 只接受 2 种结果,要么 SUCCESS ,要么 FAILURE 。
* 如果评估结果是 RUNNING ,则终止任务,改结果为 FAILURE 。
*/
public evaluate(): Status;
生命周期
行为树的生命周期
/**
* 行为树加载完成时调用。
*/
protected onLoad?(): void;
/**
* 行为树第一次执行前调用。
*/
protected onReady?(): void;
/**
* 行为树销毁时调用。
*/
protected onDestroy?(): void;
/**
* 行为树暂停时调用。
*/
protected onPause?(): void;
/**
* 行为树恢复执行时调用。
*/
protected onResume?(): void;
/**
* 行为树每次执行结束时调用。
*/
public onBehaviorComplete(): void;
任务的生命周期
/**
* 任务开始执行。
* 如果返回 true ,则继续执行。
* 如果返回 false ,则直接执行失败,结果为 FAILURE 。
*/
protected onEnter?(): boolean;
/**
* 执行任务,并返回结果。
* 1. 如果不实现 onUpdate ,默认执行结果为 FAILURE 。
* 2. 返回 SUCCESS 或 FAILURE 时,任务结束。接着调用 onExit 。
* 3. 返回 RUNNING 时表示任务正在执行。onExit 不会被调用,而是在下一次
* tick 时继续调用 onUpdate 。
*/
protected onUpdate?(): Status;
/**
* 任务执行过程中被打断。
*/
protected onAbort?(): void;
/**
* 任务执行结束。
*/
protected onExit?(): void;