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 只支持 treescene 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;

results matching ""

    No results matching ""