mirror of
https://github.com/gongxh0901/kunpocc-behaviortree.git
synced 2025-12-26 16:48:56 +00:00
行为树逻辑调整,删除非记忆的选择和顺序节点
This commit is contained in:
@@ -1,66 +0,0 @@
|
||||
/**
|
||||
* @Author: Gongxh
|
||||
* @Date: 2025-09-01
|
||||
* @Description: 抽象节点基类
|
||||
*/
|
||||
|
||||
import { IBlackboard } from "../Blackboard";
|
||||
import { BTNode, IBTNode } from "./BTNode";
|
||||
|
||||
/**
|
||||
* 叶子节点 基类
|
||||
* 没有子节点
|
||||
*/
|
||||
export abstract class LeafNode extends BTNode {
|
||||
constructor() {
|
||||
super([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修饰节点 基类
|
||||
* 有且仅有一个子节点
|
||||
*/
|
||||
export abstract class Decorator extends BTNode {
|
||||
constructor(child: IBTNode) {
|
||||
super([child]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组合节点 基类
|
||||
* 多个子节点
|
||||
*/
|
||||
export abstract class Composite extends BTNode {
|
||||
constructor(...children: IBTNode[]) {
|
||||
super(children);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数值型修饰节点 基类
|
||||
* 包含最大值和当前值的通用逻辑,适用于所有需要数值计数的修饰节点
|
||||
*/
|
||||
export abstract class NumericDecorator extends Decorator {
|
||||
protected _value: number = 0;
|
||||
protected override open(): void {
|
||||
super.open();
|
||||
this._value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记忆修饰节点基类
|
||||
* 只有记忆节点才需要设置局部数据
|
||||
*/
|
||||
export abstract class MemoryComposite extends Composite {
|
||||
public override _initialize(global: IBlackboard, branch: IBlackboard): void {
|
||||
super._initialize(global, branch);
|
||||
this._local = branch.createChild();
|
||||
}
|
||||
|
||||
protected override open(): void {
|
||||
super.open();
|
||||
this.set(`__nMemoryRunningIndex`, 0);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,16 @@
|
||||
import { BT } from "../BT";
|
||||
import { Status } from "../header";
|
||||
import { LeafNode } from "./AbstractNodes";
|
||||
import { BTNode } from "./BTNode";
|
||||
|
||||
/**
|
||||
* 叶子节点 基类
|
||||
* 没有子节点
|
||||
*/
|
||||
export abstract class LeafNode extends BTNode {
|
||||
constructor() {
|
||||
super([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 次数等待节点(无子节点)
|
||||
@@ -56,12 +66,12 @@ export class WaitTime extends LeafNode {
|
||||
|
||||
protected override open(): void {
|
||||
super.open();
|
||||
this._value = new Date().getTime();
|
||||
this._value = 0;
|
||||
}
|
||||
|
||||
public tick(): Status {
|
||||
const currTime = new Date().getTime();
|
||||
if (currTime - this._value >= this._max * 1000) {
|
||||
public tick(dt: number): Status {
|
||||
this._value += dt;
|
||||
if (this._value >= this._max) {
|
||||
return Status.SUCCESS;
|
||||
}
|
||||
return Status.RUNNING;
|
||||
|
||||
@@ -15,8 +15,8 @@ export interface IBTNode {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_execute(): Status;
|
||||
tick(): Status;
|
||||
_execute(dt: number): Status;
|
||||
tick(dt: number): Status;
|
||||
|
||||
/**
|
||||
* 优先写入自己的黑板数据, 如果没有则写入父节点的黑板数据
|
||||
@@ -67,7 +67,7 @@ export abstract class BTNode implements IBTNode {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public _execute(): Status {
|
||||
public _execute(dt: number): Status {
|
||||
// 首次执行时初始化
|
||||
const isRunning = this._local.openNodes.get(this) || false;
|
||||
if (!isRunning) {
|
||||
@@ -76,7 +76,7 @@ export abstract class BTNode implements IBTNode {
|
||||
}
|
||||
|
||||
// 执行核心逻辑
|
||||
const status = this.tick();
|
||||
const status = this.tick(dt);
|
||||
|
||||
// 执行完成时清理
|
||||
if (status !== Status.RUNNING) {
|
||||
@@ -98,7 +98,7 @@ export abstract class BTNode implements IBTNode {
|
||||
* 子类必须实现此方法
|
||||
* @returns 执行状态
|
||||
*/
|
||||
public abstract tick(): Status;
|
||||
public abstract tick(dt: number): Status;
|
||||
|
||||
/**
|
||||
* 清理节点(执行完成时调用)
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
import { IBlackboard } from "../Blackboard";
|
||||
import { BT } from "../BT";
|
||||
import { Status } from "../header";
|
||||
import { Composite, MemoryComposite } from "./AbstractNodes";
|
||||
import { IBTNode } from "./BTNode";
|
||||
import { BTNode, IBTNode } from "./BTNode";
|
||||
import { WeightDecorator } from "./Decorator";
|
||||
|
||||
/**
|
||||
* 组合节点基类
|
||||
* 有多个子节点
|
||||
*/
|
||||
export abstract class Composite extends BTNode {
|
||||
constructor(...children: IBTNode[]) {
|
||||
super(children);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记忆选择节点 从上到下执行
|
||||
* 遇到 FAILURE 继续下一个
|
||||
@@ -11,23 +21,29 @@ import { WeightDecorator } from "./Decorator";
|
||||
*
|
||||
* 遇到 RUNNING 返回 RUNNING 下次从该节点开始
|
||||
*/
|
||||
@BT.CompositeNode("MemSelector", {
|
||||
name: "记忆选择节点",
|
||||
group: "基础组合节点",
|
||||
desc: "记住上次运行位置的选择节点,从记忆位置开始执行",
|
||||
})
|
||||
export class MemSelector extends MemoryComposite {
|
||||
public tick(): Status {
|
||||
let index = this.get<number>(`__nMemoryRunningIndex`);
|
||||
@BT.CompositeNode("Selector", { name: "选择节点", group: "基础组合节点", desc: "选择节点" })
|
||||
export class Selector extends Composite {
|
||||
public override _initialize(global: IBlackboard, branch: IBlackboard): void {
|
||||
super._initialize(global, branch);
|
||||
this._local = branch.createChild();
|
||||
}
|
||||
|
||||
protected override open(): void {
|
||||
super.open();
|
||||
this.set(`__nRunningIndex`, 0);
|
||||
}
|
||||
|
||||
public tick(dt: number): Status {
|
||||
let index = this.get<number>(`__nRunningIndex`);
|
||||
for (let i = index; i < this.children.length; i++) {
|
||||
let status = this.children[i]!._execute();
|
||||
let status = this.children[i]!._execute(dt);
|
||||
if (status === Status.FAILURE) {
|
||||
continue;
|
||||
}
|
||||
if (status === Status.SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
this.set(`__nMemoryRunningIndex`, i);
|
||||
this.set(`__nRunningIndex`, i);
|
||||
return Status.RUNNING;
|
||||
}
|
||||
return Status.FAILURE;
|
||||
@@ -35,29 +51,35 @@ export class MemSelector extends MemoryComposite {
|
||||
}
|
||||
|
||||
/**
|
||||
* 记忆顺序节点 从上到下执行
|
||||
* 顺序节点 从上到下执行
|
||||
* 遇到 SUCCESS 继续下一个
|
||||
* 遇到 FAILURE 停止迭代 返回 FAILURE 下次重新开始
|
||||
*
|
||||
* 遇到 RUNNING 返回 RUNNING 下次从该节点开始
|
||||
*/
|
||||
@BT.CompositeNode("MemSequence", {
|
||||
name: "记忆顺序节点",
|
||||
group: "基础组合节点",
|
||||
desc: "记住上次运行位置的序列节点,从记忆位置开始执行",
|
||||
})
|
||||
export class MemSequence extends MemoryComposite {
|
||||
public tick(): Status {
|
||||
let index = this.get<number>(`__nMemoryRunningIndex`);
|
||||
@BT.CompositeNode("Sequence", { name: "顺序节点", group: "基础组合节点", desc: "顺序节点" })
|
||||
export class Sequence extends Composite {
|
||||
public override _initialize(global: IBlackboard, branch: IBlackboard): void {
|
||||
super._initialize(global, branch);
|
||||
this._local = branch.createChild();
|
||||
}
|
||||
|
||||
protected override open(): void {
|
||||
super.open();
|
||||
this.set(`__nRunningIndex`, 0);
|
||||
}
|
||||
|
||||
public tick(dt: number): Status {
|
||||
let index = this.get<number>(`__nRunningIndex`);
|
||||
for (let i = index; i < this.children.length; i++) {
|
||||
let status = this.children[i]!._execute();
|
||||
let status = this.children[i]!._execute(dt);
|
||||
if (status === Status.SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
if (status === Status.FAILURE) {
|
||||
return Status.FAILURE;
|
||||
}
|
||||
this.set(`__nMemoryRunningIndex`, i);
|
||||
this.set(`__nRunningIndex`, i);
|
||||
return Status.RUNNING;
|
||||
}
|
||||
return Status.SUCCESS;
|
||||
@@ -65,24 +87,22 @@ export class MemSequence extends MemoryComposite {
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择节点 从上到下执行
|
||||
* 返回第一个不为 FAILURE 的子节点状态
|
||||
* 否则返回 FAILURE
|
||||
* 并行节点 从上到下执行 全部执行一遍
|
||||
* 返回优先级 FAILURE > RUNNING > SUCCESS
|
||||
*/
|
||||
@BT.CompositeNode("Selector", {
|
||||
name: "选择节点",
|
||||
group: "基础组合节点",
|
||||
desc: "依次执行子节点,直到找到成功或运行中的节点",
|
||||
})
|
||||
export class Selector extends Composite {
|
||||
public tick(): Status {
|
||||
@BT.CompositeNode("Parallel", { name: "并行节点", group: "基础组合节点", desc: "同时执行所有子节点,全部成功才返回成功" })
|
||||
export class Parallel extends Composite {
|
||||
public tick(dt: number): Status {
|
||||
let result = Status.SUCCESS;
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
let status = this.children[i]!._execute();
|
||||
if (status !== Status.FAILURE) {
|
||||
return status;
|
||||
let status = this.children[i]!._execute(dt);
|
||||
if (result === Status.FAILURE || status === Status.FAILURE) {
|
||||
result = Status.FAILURE;
|
||||
} else if (status === Status.RUNNING) {
|
||||
result = Status.RUNNING;
|
||||
}
|
||||
}
|
||||
return Status.FAILURE;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +137,7 @@ export class RandomSelector extends Composite {
|
||||
return (child instanceof WeightDecorator) ? (child.weight) : 1;
|
||||
}
|
||||
|
||||
public tick(): Status {
|
||||
public tick(dt: number): Status {
|
||||
if (this.children.length === 0) {
|
||||
return Status.FAILURE;
|
||||
}
|
||||
@@ -139,58 +159,11 @@ export class RandomSelector extends Composite {
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
const status = this.children[childIndex]!._execute();
|
||||
const status = this.children[childIndex]!._execute(dt);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 顺序节点 从上到下执行
|
||||
* 遇到 SUCCESS 继续下一个
|
||||
* 否则返回子节点状态
|
||||
*/
|
||||
@BT.CompositeNode("Sequence", {
|
||||
name: "顺序节点",
|
||||
group: "基础组合节点",
|
||||
desc: "依次执行所有子节点,全部成功才返回成功",
|
||||
})
|
||||
export class Sequence extends Composite {
|
||||
public tick(): Status {
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
let status = this.children[i]!._execute();
|
||||
if (status === Status.SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
return Status.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 并行节点 从上到下执行 全部执行一遍
|
||||
* 返回优先级 FAILURE > RUNNING > SUCCESS
|
||||
*/
|
||||
@BT.CompositeNode("Parallel", {
|
||||
name: "并行节点",
|
||||
group: "基础组合节点",
|
||||
desc: "同时执行所有子节点,全部成功才返回成功",
|
||||
})
|
||||
export class Parallel extends Composite {
|
||||
public tick(): Status {
|
||||
let result = Status.SUCCESS;
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
let status = this.children[i]!._execute();
|
||||
if (result === Status.FAILURE || status === Status.FAILURE) {
|
||||
result = Status.FAILURE;
|
||||
} else if (status === Status.RUNNING) {
|
||||
result = Status.RUNNING;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 并行节点 从上到下执行 全部执行一遍
|
||||
* 返回优先级 SUCCESS > RUNNING > FAILURE
|
||||
@@ -201,10 +174,10 @@ export class Parallel extends Composite {
|
||||
desc: "同时执行所有子节点,任意一个成功即返回成功",
|
||||
})
|
||||
export class ParallelAnySuccess extends Composite {
|
||||
public tick(): Status {
|
||||
public tick(dt: number): Status {
|
||||
let result = Status.FAILURE;
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
let status = this.children[i]!._execute();
|
||||
let status = this.children[i]!._execute(dt);
|
||||
if (result === Status.SUCCESS || status === Status.SUCCESS) {
|
||||
result = Status.SUCCESS;
|
||||
} else if (status === Status.RUNNING) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { Status } from "../header";
|
||||
import { Decorator, LeafNode } from "./AbstractNodes";
|
||||
import { LeafNode } from "./Action";
|
||||
|
||||
/** 条件叶子节点 */
|
||||
export abstract class Condition extends LeafNode {
|
||||
@@ -18,17 +18,4 @@ export abstract class Condition extends LeafNode {
|
||||
public tick(): Status {
|
||||
return this.isEligible() ? Status.SUCCESS : Status.FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/** 条件装饰节点 */
|
||||
export abstract class ConditionDecorator extends Decorator {
|
||||
/**
|
||||
* 判断是否满足条件
|
||||
* @returns 是否满足条件
|
||||
*/
|
||||
protected abstract isEligible(): boolean;
|
||||
|
||||
public tick(): Status {
|
||||
return this.isEligible() ? this.children[0]!._execute() : Status.FAILURE;
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,30 @@
|
||||
|
||||
import { BT } from "../BT";
|
||||
import { Status } from "../header";
|
||||
import { Decorator, NumericDecorator } from "./AbstractNodes";
|
||||
import { IBTNode } from "./BTNode";
|
||||
import { BTNode, IBTNode } from "./BTNode";
|
||||
|
||||
/**
|
||||
* 修饰节点 基类
|
||||
* 有且仅有一个子节点
|
||||
*/
|
||||
export abstract class Decorator extends BTNode {
|
||||
constructor(child: IBTNode) {
|
||||
super([child]);
|
||||
}
|
||||
}
|
||||
|
||||
/** 条件装饰节点基类 */
|
||||
export abstract class ConditionDecorator extends Decorator {
|
||||
/**
|
||||
* 判断是否满足条件
|
||||
* @returns 是否满足条件
|
||||
*/
|
||||
protected abstract isEligible(): boolean;
|
||||
|
||||
public tick(dt: number): Status {
|
||||
return this.isEligible() ? this.children[0]!._execute(dt) : Status.FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 结果反转节点
|
||||
@@ -15,14 +37,10 @@ import { IBTNode } from "./BTNode";
|
||||
* 第一个Child Node节点, 返回 FAILURE, 本Node向自己的Parent Node也返回 SUCCESS
|
||||
* 第一个Child Node节点, 返回 SUCCESS, 本Node向自己的Parent Node也返回 FAILURE
|
||||
*/
|
||||
@BT.DecoratorNode("Inverter", {
|
||||
name: "反转器",
|
||||
group: "基础装饰节点",
|
||||
desc: "反转子节点的执行结果,成功变失败,失败变成功",
|
||||
})
|
||||
@BT.DecoratorNode("Inverter", { name: "反转器", group: "基础装饰节点", desc: "反转子节点的执行结果,成功变失败,失败变成功" })
|
||||
export class Inverter extends Decorator {
|
||||
public tick(): Status {
|
||||
const status = this.children[0]!._execute();
|
||||
public tick(dt: number): Status {
|
||||
const status = this.children[0]!._execute(dt);
|
||||
|
||||
if (status === Status.SUCCESS) {
|
||||
return Status.FAILURE;
|
||||
@@ -40,15 +58,12 @@ export class Inverter extends Decorator {
|
||||
* 规定时间内, 根据Child Node的结果, 本节点向自己的父节点也返回相同的结果
|
||||
* 超时后, 直接返回 FAILURE
|
||||
*/
|
||||
@BT.DecoratorNode("LimitTime", {
|
||||
name: "时间限制器",
|
||||
group: "基础装饰节点",
|
||||
desc: "限制子节点执行时间,超时返回失败",
|
||||
})
|
||||
export class LimitTime extends NumericDecorator {
|
||||
@BT.DecoratorNode("LimitTime", { name: "时间限制器", group: "基础装饰节点", desc: "限制子节点执行时间,超时返回失败" })
|
||||
export class LimitTime extends Decorator {
|
||||
@BT.prop({ type: BT.ParamType.float, description: "最大时间(秒)", defaultValue: 1 })
|
||||
protected _max: number = 1;
|
||||
|
||||
private _value: number = 0;
|
||||
/**
|
||||
* 时间限制节点
|
||||
* @param child 子节点
|
||||
@@ -60,15 +75,15 @@ export class LimitTime extends NumericDecorator {
|
||||
}
|
||||
|
||||
protected override open(): void {
|
||||
this._value = Date.now();
|
||||
this._value = 0;
|
||||
}
|
||||
|
||||
public tick(): Status {
|
||||
const currentTime = Date.now();
|
||||
if (currentTime - this._value > this._max * 1000) {
|
||||
public tick(dt: number): Status {
|
||||
this._value += dt;
|
||||
if (this._value > this._max) {
|
||||
return Status.FAILURE;
|
||||
}
|
||||
return this.children[0]!._execute();
|
||||
return this.children[0]!._execute(dt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,25 +92,27 @@ export class LimitTime extends NumericDecorator {
|
||||
* 必须且只能包含一个子节点
|
||||
* 次数超过后, 直接返回失败; 次数未超过, 返回子节点状态
|
||||
*/
|
||||
@BT.DecoratorNode("LimitTicks", {
|
||||
name: "次数限制器",
|
||||
group: "基础装饰节点",
|
||||
desc: "限制子节点执行次数,超过次数返回失败",
|
||||
})
|
||||
export class LimitTicks extends NumericDecorator {
|
||||
@BT.DecoratorNode("LimitTicks", { name: "次数限制器", group: "基础装饰节点", desc: "限制子节点执行次数,超过次数返回失败" })
|
||||
export class LimitTicks extends Decorator {
|
||||
@BT.prop({ type: BT.ParamType.int, description: "最大次数", defaultValue: 1 })
|
||||
protected _max: number = 1;
|
||||
|
||||
private _value: number = 0;
|
||||
constructor(child: IBTNode, max: number = 1) {
|
||||
super(child);
|
||||
this._max = max;
|
||||
}
|
||||
|
||||
public tick(): Status {
|
||||
protected override open(): void {
|
||||
this._value = 0;
|
||||
}
|
||||
|
||||
public tick(dt: number): Status {
|
||||
this._value++;
|
||||
if (this._value > this._max) {
|
||||
return Status.FAILURE;
|
||||
}
|
||||
return this.children[0]!._execute();
|
||||
return this.children[0]!._execute(dt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,21 +122,24 @@ export class LimitTicks extends NumericDecorator {
|
||||
* 子节点是成功或失败,累加计数
|
||||
* 次数超过之后返回子节点状态,否则返回 RUNNING
|
||||
*/
|
||||
@BT.DecoratorNode("Repeat", {
|
||||
name: "重复节点",
|
||||
group: "基础装饰节点",
|
||||
desc: "重复执行子节点指定次数",
|
||||
})
|
||||
export class Repeat extends NumericDecorator {
|
||||
@BT.DecoratorNode("Repeat", { name: "重复节点", group: "基础装饰节点", desc: "重复执行子节点指定次数" })
|
||||
export class Repeat extends Decorator {
|
||||
@BT.prop({ type: BT.ParamType.int, description: "重复次数", defaultValue: 1 })
|
||||
protected _max: number = 1;
|
||||
|
||||
private _value: number = 0;
|
||||
constructor(child: IBTNode, max: number = 1) {
|
||||
super(child);
|
||||
this._max = max;
|
||||
}
|
||||
public tick(): Status {
|
||||
|
||||
protected override open(): void {
|
||||
this._value = 0;
|
||||
}
|
||||
|
||||
public tick(dt: number): Status {
|
||||
// 执行子节点
|
||||
const status = this.children[0]!._execute();
|
||||
const status = this.children[0]!._execute(dt);
|
||||
// 如果子节点完成(成功或失败),增加计数
|
||||
if (status === Status.SUCCESS || status === Status.FAILURE) {
|
||||
this._value++;
|
||||
@@ -139,20 +159,23 @@ export class Repeat extends NumericDecorator {
|
||||
*
|
||||
* 子节点成功 计数+1
|
||||
*/
|
||||
@BT.DecoratorNode("RepeatUntilFailure", {
|
||||
name: "重复直到失败",
|
||||
group: "基础装饰节点",
|
||||
desc: "重复执行子节点直到失败或达到最大次数",
|
||||
})
|
||||
export class RepeatUntilFailure extends NumericDecorator {
|
||||
@BT.DecoratorNode("RepeatUntilFailure", { name: "重复直到失败", group: "基础装饰节点", desc: "重复执行子节点直到失败或达到最大次数" })
|
||||
export class RepeatUntilFailure extends Decorator {
|
||||
@BT.prop({ type: BT.ParamType.int, description: "最大重试次数", defaultValue: 1 })
|
||||
protected _max: number = 1;
|
||||
|
||||
private _value: number = 0;
|
||||
constructor(child: IBTNode, max: number = 1) {
|
||||
super(child);
|
||||
this._max = max;
|
||||
}
|
||||
public tick(): Status {
|
||||
const status = this.children[0]!._execute();
|
||||
|
||||
protected override open(): void {
|
||||
this._value = 0;
|
||||
}
|
||||
|
||||
public tick(dt: number): Status {
|
||||
const status = this.children[0]!._execute(dt);
|
||||
if (status === Status.FAILURE) {
|
||||
return Status.FAILURE;
|
||||
}
|
||||
@@ -174,21 +197,24 @@ export class RepeatUntilFailure extends NumericDecorator {
|
||||
*
|
||||
* 子节点失败, 计数+1
|
||||
*/
|
||||
@BT.DecoratorNode("RepeatUntilSuccess", {
|
||||
name: "重复直到成功",
|
||||
group: "基础装饰节点",
|
||||
desc: "重复执行子节点直到成功或达到最大次数",
|
||||
})
|
||||
export class RepeatUntilSuccess extends NumericDecorator {
|
||||
@BT.DecoratorNode("RepeatUntilSuccess", { name: "重复直到成功", group: "基础装饰节点", desc: "重复执行子节点直到成功或达到最大次数" })
|
||||
export class RepeatUntilSuccess extends Decorator {
|
||||
@BT.prop({ type: BT.ParamType.int, description: "最大重试次数", defaultValue: 1, step: 1 })
|
||||
protected _max: number = 1;
|
||||
|
||||
private _value: number = 0;
|
||||
constructor(child: IBTNode, max: number = 1) {
|
||||
super(child);
|
||||
this._max = max;
|
||||
}
|
||||
public tick(): Status {
|
||||
|
||||
protected override open(): void {
|
||||
this._value = 0;
|
||||
}
|
||||
|
||||
public tick(dt: number): Status {
|
||||
// 执行子节点
|
||||
const status = this.children[0]!._execute();
|
||||
const status = this.children[0]!._execute(dt);
|
||||
if (status === Status.SUCCESS) {
|
||||
return Status.SUCCESS;
|
||||
}
|
||||
@@ -206,11 +232,7 @@ export class RepeatUntilSuccess extends NumericDecorator {
|
||||
/**
|
||||
* 权重装饰节点
|
||||
*/
|
||||
@BT.DecoratorNode("WeightDecorator", {
|
||||
name: "权重装饰器",
|
||||
group: "基础装饰节点",
|
||||
desc: "权重装饰节点",
|
||||
})
|
||||
@BT.DecoratorNode("WeightDecorator", { name: "权重装饰器", group: "基础装饰节点", desc: "权重装饰节点" })
|
||||
export class WeightDecorator extends Decorator {
|
||||
@BT.prop({ type: BT.ParamType.int, description: "权重", defaultValue: 1, step: 1 })
|
||||
private _weight: number;
|
||||
@@ -221,8 +243,8 @@ export class WeightDecorator extends Decorator {
|
||||
this._weight = weight || 1;
|
||||
}
|
||||
|
||||
public tick(): Status {
|
||||
return this.children[0]!._execute();
|
||||
public tick(dt: number): Status {
|
||||
return this.children[0]!._execute(dt);
|
||||
}
|
||||
|
||||
public get weight(): number {
|
||||
|
||||
@@ -34,8 +34,8 @@ export class BehaviorTree<T> {
|
||||
/**
|
||||
* 执行行为树
|
||||
*/
|
||||
public tick(): Status {
|
||||
return this._root._execute();
|
||||
public tick(dt: number): Status {
|
||||
return this._root._execute(dt);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,7 @@ import { BehaviorTree } from "./BehaviorTree";
|
||||
import { BT } from "./BT";
|
||||
import { IBTNode } from "./BTNode/BTNode";
|
||||
|
||||
interface INodeConfig {
|
||||
export interface INodeConfig {
|
||||
id: string,
|
||||
className: string,
|
||||
parameters: Record<string, any>,
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
/** 行为树 */
|
||||
export { BehaviorTree } from "./behaviortree/BehaviorTree";
|
||||
export { Blackboard } from "./behaviortree/Blackboard";
|
||||
export { } from "./behaviortree/BT";
|
||||
export * from "./behaviortree/BTNode/AbstractNodes";
|
||||
export * from "./behaviortree/BTNode/Action";
|
||||
export { IBTNode } from "./behaviortree/BTNode/BTNode";
|
||||
export * from "./behaviortree/BTNode/Composite";
|
||||
export * from "./behaviortree/BTNode/Condition";
|
||||
export * from "./behaviortree/BTNode/Decorator";
|
||||
export { createBehaviorTree } from "./behaviortree/Factory";
|
||||
export { createBehaviorTree, INodeConfig } from "./behaviortree/Factory";
|
||||
export { Status } from "./behaviortree/header";
|
||||
|
||||
// 导出装饰器内容
|
||||
|
||||
Reference in New Issue
Block a user