diff --git a/src/behaviortree/BT.ts b/src/behaviortree/BT.ts index 1919ff1..8997f64 100644 --- a/src/behaviortree/BT.ts +++ b/src/behaviortree/BT.ts @@ -42,6 +42,10 @@ export namespace BT { defaultValue?: any; /** 步进 针对数字类型的变更的最小单位 */ step?: number, + /** 最小值 */ + min?: number, + /** 最大值 */ + max?: number, } /** diff --git a/src/behaviortree/BTNode/BTNode.ts b/src/behaviortree/BTNode/BTNode.ts index 7d022d6..b9ae507 100644 --- a/src/behaviortree/BTNode/BTNode.ts +++ b/src/behaviortree/BTNode/BTNode.ts @@ -81,9 +81,7 @@ export abstract class BTNode implements IBTNode { // 执行完成时清理 if (status !== Status.RUNNING) { this._local.openNodes.delete(this); - this.close(); } - return status; } @@ -93,6 +91,17 @@ export abstract class BTNode implements IBTNode { */ protected open(): void { } + /** + * 清理子节点的打开状态 + * 一般用于装饰节点的非子节点关闭时, 用来清理子节点的打开状态 + */ + protected cleanupChild(): void { + const child = this.children[0]; + if (child && this._local.openNodes.has(child)) { + this._local.openNodes.delete(child); + } + } + /** * 执行节点逻辑 * 子类必须实现此方法 @@ -100,12 +109,6 @@ export abstract class BTNode implements IBTNode { */ public abstract tick(dt: number): Status; - /** - * 清理节点(执行完成时调用) - * 子类重写此方法进行状态清理 - */ - protected close(): void { } - public getEntity(): T { return this._local.getEntity(); } diff --git a/src/behaviortree/BTNode/Decorator.ts b/src/behaviortree/BTNode/Decorator.ts index 28d09a2..aac534a 100644 --- a/src/behaviortree/BTNode/Decorator.ts +++ b/src/behaviortree/BTNode/Decorator.ts @@ -27,7 +27,10 @@ export abstract class ConditionDecorator extends Decorator { protected abstract isEligible(): boolean; public tick(dt: number): Status { - return this.isEligible() ? this.children[0]!._execute(dt) : Status.FAILURE; + if (this.isEligible()) { + return this.children[0]!._execute(dt); + } + return Status.FAILURE; } } @@ -81,6 +84,7 @@ export class LimitTime extends Decorator { public tick(dt: number): Status { this._value += dt; if (this._value > this._max) { + this.cleanupChild(); return Status.FAILURE; } return this.children[0]!._execute(dt); @@ -110,6 +114,7 @@ export class LimitTicks extends Decorator { public tick(dt: number): Status { this._value++; if (this._value > this._max) { + this.cleanupChild(); return Status.FAILURE; } return this.children[0]!._execute(dt); @@ -124,7 +129,7 @@ export class LimitTicks extends Decorator { */ @BT.DecoratorNode("Repeat", { name: "重复节点", group: "基础装饰节点", desc: "重复执行子节点指定次数" }) export class Repeat extends Decorator { - @BT.prop({ type: BT.ParamType.int, description: "重复次数", defaultValue: 1 }) + @BT.prop({ type: BT.ParamType.int, description: "重复次数", defaultValue: 1, min: 1 }) protected _max: number = 1; private _value: number = 0; @@ -161,7 +166,7 @@ export class Repeat extends Decorator { */ @BT.DecoratorNode("RepeatUntilFailure", { name: "重复直到失败", group: "基础装饰节点", desc: "重复执行子节点直到失败或达到最大次数" }) export class RepeatUntilFailure extends Decorator { - @BT.prop({ type: BT.ParamType.int, description: "最大重试次数", defaultValue: 1 }) + @BT.prop({ type: BT.ParamType.int, description: "最大重试次数", defaultValue: 1, min: 1 }) protected _max: number = 1; private _value: number = 0;