This commit is contained in:
sli97
2023-09-21 01:32:11 +08:00
commit 47104caa6e
964 changed files with 62409 additions and 0 deletions

115
dist/runtime/core/Behavior.js vendored Normal file
View File

@@ -0,0 +1,115 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BehaviorTree = void 0;
const cc_1 = require("cc");
const BehaviorEditor_1 = require("./BehaviorEditor");
const BehaviorManager_1 = require("./BehaviorManager");
const BehaviorSource_1 = require("../core/BehaviorSource");
const { ccclass, property, requireComponent } = cc_1._decorator;
/***
* 用户真正使用的组件,用来设置单个行为树的运行参数
* 改成BehaviorTree名字方便用户使用
*/
let BehaviorTree = class BehaviorTree extends cc_1.Component {
constructor() {
super(...arguments);
this.asset = null;
this.restartWhenComplete = false;
this.startWhenEnabled = true;
/***
* true节点失活的时候行为树会保留仅暂停运行
* false节点失活的时候行为树直接删除
*/
this.pauseWhenDisabled = false;
this.logNodeChange = false;
// 是否被暂停运行了(未开始执行的行为树或者被删除的树都不属于暂停)
this.isPaused = false;
// 是否执行完start生成周期防止start和onEnable重复执行enableBehavior
this.isInit = false;
this.behaviorSource = new BehaviorSource_1.BehaviorSource();
}
/***
* 仅enableBehavior和disableBehavior属于供用户在自定义脚本中管理单个行为树的方法
* 其他方法请勿使用
*/
enableBehavior() {
this.createBehaviorManager();
if (BehaviorManager_1.BehaviorManager.instance) {
BehaviorManager_1.BehaviorManager.instance.enableBehavior(this);
}
}
disableBehavior(pause = this.pauseWhenDisabled) {
if (BehaviorManager_1.BehaviorManager.instance) {
BehaviorManager_1.BehaviorManager.instance.disableBehavior(this, pause);
this.isPaused = pause;
}
}
parse() {
this.behaviorSource.parse(this.asset.json);
}
start() {
if (this.startWhenEnabled) {
this.enableBehavior();
}
this.isInit = true;
}
onEnable() {
if (!this.isInit) {
return;
}
// 运行被暂停或者startWhenEnabled的树
if (this.isPaused || this.startWhenEnabled) {
this.enableBehavior();
this.isPaused = false;
}
}
onDisable() {
this.disableBehavior();
}
createBehaviorManager() {
if (!BehaviorManager_1.BehaviorManager.instance) {
const node = new cc_1.Node("BehaviorManager");
BehaviorManager_1.BehaviorManager.instance = node.addComponent(BehaviorManager_1.BehaviorManager);
cc_1.director.getScene().addChild(node);
}
}
onBehaviorStarted() { }
/***
* 插件面板初始化时调用
*/
async getAssetUrl() {
if (!this.asset) {
return;
}
const uuid = this.asset._uuid;
// 获取当前json的url
const url = await Editor.Message.request("asset-db", "query-url", uuid);
return url;
}
};
__decorate([
property(cc_1.JsonAsset)
], BehaviorTree.prototype, "asset", void 0);
__decorate([
property(cc_1.CCBoolean)
], BehaviorTree.prototype, "restartWhenComplete", void 0);
__decorate([
property(cc_1.CCBoolean)
], BehaviorTree.prototype, "startWhenEnabled", void 0);
__decorate([
property(cc_1.CCBoolean)
], BehaviorTree.prototype, "pauseWhenDisabled", void 0);
__decorate([
property(cc_1.CCBoolean)
], BehaviorTree.prototype, "logNodeChange", void 0);
BehaviorTree = __decorate([
ccclass("BehaviorTree"),
requireComponent(BehaviorEditor_1.BehaviorEditor)
], BehaviorTree);
exports.BehaviorTree = BehaviorTree;

21
dist/runtime/core/BehaviorEditor.js vendored Normal file
View File

@@ -0,0 +1,21 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BehaviorEditor = void 0;
const cc_1 = require("cc");
const { ccclass, property } = cc_1._decorator;
/***
* 方便用户打开插件面板配合插件的contributions.inspector使用
* 详见https://docs.cocos.com/creator/manual/zh/editor/extension/inspector.html
*/
let BehaviorEditor = class BehaviorEditor extends cc_1.Component {
};
BehaviorEditor = __decorate([
ccclass("BehaviorEditor")
], BehaviorEditor);
exports.BehaviorEditor = BehaviorEditor;

540
dist/runtime/core/BehaviorManager.js vendored Normal file
View File

@@ -0,0 +1,540 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var BehaviorManager_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BehaviorManager = void 0;
const cc_1 = require("cc");
const node_1 = require("../node");
const BehaviorTree_1 = require("./BehaviorTree");
const utils_1 = require("./utils");
const { ccclass } = cc_1._decorator;
/***
* 该组件会自动添加到场景上,用来驱动、管理场景中所有行为树
*/
let BehaviorManager = BehaviorManager_1 = class BehaviorManager extends cc_1.Component {
constructor() {
super(...arguments);
this.behaviorTrees = [];
// behavior是用户使用的组件BehaviorTree是真正的行为树数据结构
this.behaviorTreesMap = new Map();
// 存储被暂停运行的行为树
this.pausedBehaviorTreesMap = new Map();
}
restart(behaviorTree) {
if (behaviorTree.behavior.logNodeChange) {
console.log("restart", behaviorTree);
}
// 所有节点都popNode出去以后未删除的条件重评估的compositeIndex都为-1
this.removeChildConditionalReevaluate(behaviorTree, -1);
this.pushNode(behaviorTree, 0, 0);
}
// 防止用户手动创建实例但没有设置instance
onLoad() {
BehaviorManager_1.instance = this;
}
onDestroy() {
for (const behaviorTree of this.behaviorTrees) {
this.disableBehavior(behaviorTree.behavior);
}
}
/***
* 不传isPause的话默认删掉行为树
*/
disableBehavior(behavior, isPause = false) {
const behaviorTree = this.behaviorTreesMap.get(behavior);
if (!behaviorTree) {
return;
}
if (isPause) {
// 存进暂停map里
this.pausedBehaviorTreesMap.set(behavior, behaviorTree);
behaviorTree.behavior.status = node_1.NodeStatus.Inactive; //设置为未激活状态
}
else {
// 如果是手动disabled的话让剩下的节点popNode并不断迭代这个状态作为最终行为树的状态
let status = node_1.NodeStatus.Success;
for (let i = behaviorTree.activeStack.length - 1; i >= 0; i--) {
const curStack = behaviorTree.activeStack[i];
for (let j = curStack.length - 1; j >= 0; j--) {
status = this.popNode(behaviorTree, curStack[curStack.length - 1], i, status, false);
}
}
behavior.status = status;
this.removeChildConditionalReevaluate(behaviorTree, -1);
behavior.emit(BehaviorTree_1.BehaviorTreeEvent.BehaviorTreeEnd);
this.behaviorTreesMap.delete(behavior);
}
const index = this.behaviorTrees.findIndex((tree) => tree === behaviorTree);
// 数组删除该树
index > -1 && this.behaviorTrees.splice(index, 1);
}
enableBehavior(behavior) {
const rootNode = behavior.behaviorSource.rootNode;
if (!rootNode) {
if (behavior.logNodeChange) {
console.warn("该行为树没有根节点");
}
return;
}
// 仅被暂停的树从map里拿出来继续运行
if (this.pausedBehaviorTreesMap.has(behavior)) {
const behaviorTree = this.pausedBehaviorTreesMap.get(behavior);
this.pausedBehaviorTreesMap.delete(behavior);
this.behaviorTrees.push(behaviorTree);
this.behaviorTreesMap.set(behavior, behaviorTree);
return;
}
// 全新的树
const behaviorTree = new BehaviorTree();
behaviorTree.behavior = behavior;
this.behaviorTrees.push(behaviorTree);
this.behaviorTreesMap.set(behavior, behaviorTree);
//填充数据结构
behaviorTree.activeStack.push([]);
behaviorTree.parentIndex.push(-1);
behaviorTree.relativeChildIndex.push(-1);
behaviorTree.parentCompositeIndex.push(-1);
this.addToNodeList(behaviorTree, rootNode, { parentCompositeIndex: -1 });
//根节点放入运行栈
behaviorTree.behavior.emit(BehaviorTree_1.BehaviorTreeEvent.BehaviorTreeStart);
behaviorTree.behavior.status = node_1.NodeStatus.Running;
//根节点放入运行栈
this.pushNode(behaviorTree, 0, 0);
}
// 数据结构填充
addToNodeList(behaviorTree, node, data) {
behaviorTree.nodeList.push(node);
const index = behaviorTree.nodeList.length - 1;
if (node instanceof node_1.ParentNode) {
behaviorTree.childrenIndex.push([]);
behaviorTree.childConditionalIndex.push([]);
for (let i = 0; i < node.children.length; i++) {
behaviorTree.parentIndex.push(index);
behaviorTree.relativeChildIndex.push(i);
behaviorTree.childrenIndex[index].push(behaviorTree.nodeList.length);
if (node instanceof node_1.Composite) {
data.parentCompositeIndex = index;
}
behaviorTree.parentCompositeIndex.push(data.parentCompositeIndex);
this.addToNodeList(behaviorTree, node.children[i], data);
}
}
else {
behaviorTree.childrenIndex.push(null);
behaviorTree.childConditionalIndex.push(null);
if (node instanceof node_1.Condition) {
const parentCompositeIndex = behaviorTree.parentCompositeIndex[index];
if (parentCompositeIndex !== -1) {
behaviorTree.childConditionalIndex[parentCompositeIndex].push(index);
}
}
}
}
update() {
this.tick();
}
/***
* 驱动所有行为树
*/
tick() {
//遍历所有树
for (const behaviorTree of this.behaviorTrees) {
if (behaviorTree.behavior.logNodeChange) {
console.log("tick", behaviorTree);
}
// 重评估条件
this.reevaluateConditionalNode(behaviorTree);
//遍历所有运行栈
//
for (let i = behaviorTree.activeStack.length - 1; i >= 0; i--) {
const curStack = behaviorTree.activeStack[i];
let prevIndex = -1;
let prevStatus = node_1.NodeStatus.Inactive;
while (prevStatus !== node_1.NodeStatus.Running && i < behaviorTree.activeStack.length && curStack.length) {
const curIndex = curStack[curStack.length - 1];
// 记录前后两次防止repeater子节点状态为success时在一个tick里重复运行
if (curIndex === prevIndex) {
break;
}
prevIndex = curIndex;
// runNode需要传入prevStatus的原因是
// 例如selector一个子节点是running状态某个tick变成了success状态子节点popNode出去
// 下一个tick进来栈顶元素是selector此时canExecute为falserunParentNode没办法返回一个具体的状态
// 此时就可以把上一个tick子节点的状态作为本次tick的selector的状态反转节点同理
prevStatus = this.runNode(behaviorTree, curIndex, i, prevStatus);
}
}
}
}
runNode(behaviorTree, index, stackIndex, prevStatus) {
const node = behaviorTree.nodeList[index];
// 保证运行的节点在栈顶
this.pushNode(behaviorTree, index, stackIndex);
let status = prevStatus;
if (node instanceof node_1.ParentNode) {
status = this.runParentNode(behaviorTree, index, stackIndex, status);
// 并行节点的状态不由某个子节点状态决定而是由多个共同决定所以重新计算status
status = node.overrideStatus(status);
}
else {
// 执行目标事件
const res1 = node.onUpdate();
const [done, res2] = this.emitEvent(behaviorTree, node.data, "onUpdate");
status = done ? res2 : res1;
}
// 非running的节点pop出去
if (status !== node_1.NodeStatus.Running) {
status = this.popNode(behaviorTree, index, stackIndex, status);
}
return status;
}
runParentNode(behaviorTree, index, stackIndex, status) {
const node = behaviorTree.nodeList[index];
//防止running状态的并行节点重复运行
if (node.canRunParallelChildren() && node.overrideStatus(node_1.NodeStatus.Running) === node_1.NodeStatus.Running) {
return status;
}
let childStatus = node_1.NodeStatus.Inactive;
let preIndex = -1;
//并行节点可以存在多个running状态的子节点
while (node.canExecute() && (childStatus !== node_1.NodeStatus.Running || node.canRunParallelChildren())) {
const childIndex = node.index;
// 并行节点创建新的运行栈
if (node.canRunParallelChildren()) {
behaviorTree.activeStack.push([]);
stackIndex = behaviorTree.activeStack.length - 1;
node.onChildStarted();
}
let curIndex = childIndex;
// 防止repeater或untilSuccess等可以重复运行的节点canExecute一直是true会导致一直进入while
// 所以加入curIndex和preIndex保证不能在一次runParentNode里重复运行相同节点
if (curIndex === preIndex) {
status = node_1.NodeStatus.Running;
break;
}
preIndex = curIndex;
status = childStatus = this.runNode(behaviorTree, behaviorTree.childrenIndex[index][childIndex], stackIndex, status);
}
// 子节点有运行就返回子节点的状态,没有就返回上一次运行的状态
return status;
}
pushNode(behaviorTree, index, stackIndex) {
const stack = behaviorTree.activeStack[stackIndex];
// 防止重复推入
if (stack.length === 0 || stack[stack.length - 1] !== index) {
stack.push(index);
const node = behaviorTree.nodeList[index];
if (behaviorTree.behavior.logNodeChange) {
console.log("pushNode", node, "index:", index, "stackIndex:", stackIndex);
}
node.onStart();
this.emitEvent(behaviorTree, node.data, "onStart");
}
}
popNode(behaviorTree, index, stackIndex, status, popChildren = true) {
const curStack = behaviorTree.activeStack[stackIndex];
curStack.pop();
const node = behaviorTree.nodeList[index];
node.onEnd();
this.emitEvent(behaviorTree, node.data, "onEnd");
if (behaviorTree.behavior.logNodeChange) {
console.log("popNode", node, "index:", index, "stackIndex:", stackIndex, "status:", status);
}
const parentIndex = behaviorTree.parentIndex[index];
if (parentIndex !== -1) {
if (node instanceof node_1.Condition) {
const parentCompositeIndex = behaviorTree.parentCompositeIndex[index];
if (parentCompositeIndex !== -1) {
const composite = behaviorTree.nodeList[parentCompositeIndex];
//自己是条件节点并且父级的中断类型存在,创建重判断实例
if (composite.abortType !== node_1.AbortType.None) {
// 父composite为LowerPriority时条件重评估不希望此时执行而是父composite popNode出去再执行
const compositeIndex = composite.abortType === node_1.AbortType.LowerPriority ? -1 : parentCompositeIndex;
// 防止该条件存在条件重评估对象
if (behaviorTree.conditionalReevaluateMap.has(index)) {
const conditionalReevaluate = behaviorTree.conditionalReevaluateMap.get(index);
conditionalReevaluate.compositeIndex = compositeIndex;
conditionalReevaluate.status = status;
}
else {
const conditionalReevaluate = new ConditionalReevaluate(index, stackIndex, status, compositeIndex);
if (behaviorTree.behavior.logNodeChange) {
console.log("new ConditionalReevaluate", conditionalReevaluate, "index:", index, "stackIndex:", stackIndex, "compositeIndex", compositeIndex);
}
behaviorTree.conditionalReevaluate.push(conditionalReevaluate);
behaviorTree.conditionalReevaluateMap.set(index, conditionalReevaluate);
}
}
}
}
const parentNode = behaviorTree.nodeList[parentIndex];
parentNode.onChildExecuted(status, behaviorTree.relativeChildIndex[index]);
// 父节点是反转节点,修改结果
if (parentNode instanceof node_1.Decorator) {
status = parentNode.decorate(status);
}
}
if (node instanceof node_1.Composite) {
// 类型是Self或者None时清空所有子条件重评估或者popNode的节点是当前运行栈的最后一项删除该节点管理的条件重评估
if ([node_1.AbortType.Self, node_1.AbortType.None].includes(node.abortType) || !curStack.length) {
this.removeChildConditionalReevaluate(behaviorTree, index);
// 类型是LowerPriority或者Both上移compositeIndexcompositeIndex为-1的条件重评估对象LowerPriority会因此激活
}
else if ([node_1.AbortType.LowerPriority, node_1.AbortType.Both].includes(node.abortType)) {
for (let i = 0; i < behaviorTree.childConditionalIndex[index].length; i++) {
const childConditionalIndex = behaviorTree.childConditionalIndex[index][i];
if (behaviorTree.conditionalReevaluateMap.has(childConditionalIndex)) {
const conditionalReevaluate = behaviorTree.conditionalReevaluateMap.get(childConditionalIndex);
conditionalReevaluate.compositeIndex = behaviorTree.parentCompositeIndex[index];
}
}
// 上移当前被移除的composite管理的所有条件重评估的compositeIndex
for (let i = 0; i < behaviorTree.conditionalReevaluate.length; i++) {
const conditionalReevaluate = behaviorTree.conditionalReevaluate[i];
if (conditionalReevaluate.compositeIndex === index) {
conditionalReevaluate.compositeIndex = behaviorTree.parentCompositeIndex[index];
}
}
}
}
if (popChildren) {
//并行节点删除其他正在运行的子节点
for (let i = behaviorTree.activeStack.length - 1; i > stackIndex; i--) {
const stack = behaviorTree.activeStack[i];
if (stack.length > 0 && this.isParentNode(behaviorTree, index, stack[stack.length - 1])) {
let status = node_1.NodeStatus.Failure;
for (let j = stack.length - 1; j >= 0; j--) {
status = this.popNode(behaviorTree, stack[stack.length - 1], i, status, false);
}
}
}
}
// 当前运行栈没有节点了
if (curStack.length === 0) {
// 当前运行栈就是主运行栈
if (stackIndex === 0) {
// 重启行为树
if (behaviorTree.behavior.restartWhenComplete) {
this.restart(behaviorTree);
}
else {
this.disableBehavior(behaviorTree.behavior);
//修改disableBehavior写入的status
behaviorTree.behavior.status = status;
}
status = node_1.NodeStatus.Inactive;
}
else {
// 删除其他空子运行栈
behaviorTree.activeStack.splice(stackIndex, 1);
// 返回running退出tick的while循环
status = node_1.NodeStatus.Running;
}
}
return status;
}
reevaluateConditionalNode(behaviorTree) {
if (behaviorTree.behavior.logNodeChange) {
console.log("reevaluateConditionalNode start", behaviorTree.conditionalReevaluate);
}
for (let i = behaviorTree.conditionalReevaluate.length - 1; i >= 0; i--) {
const { index, compositeIndex, status: prevStatus } = behaviorTree.conditionalReevaluate[i];
//父组合节点索引不存在或者故意设置为-1不进行评估
if (compositeIndex === -1) {
continue;
}
const node = behaviorTree.nodeList[index];
let status = node_1.NodeStatus.Inactive;
const res1 = node.onUpdate();
const [done, res2] = this.emitEvent(behaviorTree, node.data, "onUpdate");
status = done ? res2 : res1;
//条件一致
if (status === prevStatus) {
continue;
}
if (behaviorTree.behavior.logNodeChange) {
console.log("reevaluateConditionalNode success", behaviorTree.conditionalReevaluate[i]);
}
for (let j = behaviorTree.activeStack.length - 1; j >= 0; j--) {
const stack = behaviorTree.activeStack[j];
if (!stack.length) {
continue;
}
//当前节点及他到公共父节点之间所有父节点pop出去
let curNodeIndex = stack[stack.length - 1];
const commonParentIndex = this.findCommonParentIndex(behaviorTree, curNodeIndex, index);
// 该条件重评估的compositeIndex是commonParent的父级
if (this.isParentNode(behaviorTree, compositeIndex, commonParentIndex)) {
// popNode可能会修改activeStack保存一下长度相同才执行
const stackLen = behaviorTree.activeStack.length;
while (curNodeIndex !== -1 &&
curNodeIndex !== commonParentIndex &&
behaviorTree.activeStack.length === stackLen) {
this.popNode(behaviorTree, curNodeIndex, j, node_1.NodeStatus.Failure, false);
curNodeIndex = behaviorTree.parentIndex[curNodeIndex];
}
}
}
//右边的包括自己的重评估条件删除掉
for (let j = behaviorTree.conditionalReevaluate.length - 1; j >= i; j--) {
const conditionalReevaluate = behaviorTree.conditionalReevaluate[j];
if (this.isParentNode(behaviorTree, compositeIndex, conditionalReevaluate.index)) {
behaviorTree.conditionalReevaluateMap.delete(conditionalReevaluate.index);
behaviorTree.conditionalReevaluate.splice(j, 1);
}
}
const compositeNode = behaviorTree.nodeList[behaviorTree.parentCompositeIndex[index]];
// 遍历左侧的条件重评估对象
for (let j = i - 1; j >= 0; j--) {
const conditionalReevaluate = behaviorTree.conditionalReevaluate[j];
if (behaviorTree.parentCompositeIndex[conditionalReevaluate.index] === behaviorTree.parentCompositeIndex[index]) {
// composite节点是LowerPriority则让这些条件停止运行
if (compositeNode.abortType === node_1.AbortType.LowerPriority) {
conditionalReevaluate.compositeIndex = -1;
// composite节点是Both或者Self条件重评估的compositeIndex等于parentCompositeIndex
}
else if ([node_1.AbortType.Both, node_1.AbortType.Self].includes(compositeNode.abortType)) {
conditionalReevaluate.index = behaviorTree.parentCompositeIndex[index];
}
}
}
//当前条件节点到CommonParentNode之间所有Composite节点执行onConditionalAbort
const conditionalParentIndex = [];
for (let m = behaviorTree.parentIndex[index]; m != compositeIndex; m = behaviorTree.parentIndex[m]) {
conditionalParentIndex.push(m);
}
conditionalParentIndex.push(compositeIndex);
//从顶部到底部的顺序执行
for (let n = conditionalParentIndex.length - 1; n >= 0; n--) {
const parentTask = behaviorTree.nodeList[conditionalParentIndex[n]];
if (n === 0) {
parentTask.onConditionalAbort(behaviorTree.relativeChildIndex[index]);
}
else {
parentTask.onConditionalAbort(behaviorTree.relativeChildIndex[conditionalParentIndex[n - 1]]);
}
}
}
}
removeChildConditionalReevaluate(behaviorTree, compositeIndex) {
for (let i = behaviorTree.conditionalReevaluate.length - 1; i >= 0; i--) {
if (behaviorTree.conditionalReevaluate[i].compositeIndex === compositeIndex) {
behaviorTree.conditionalReevaluateMap.delete(behaviorTree.conditionalReevaluate[i].index);
behaviorTree.conditionalReevaluate.splice(i, 1);
}
}
}
findCommonParentIndex(behaviorTree, index1, index2) {
const set = new Set();
let num = index1;
while (num !== -1) {
set.add(num);
num = behaviorTree.parentIndex[num];
}
num = index2;
while (!set.has(num)) {
num = behaviorTree.parentIndex[num];
}
return num;
}
isParentNode(behaviorTree, possibleParent, possibleChild) {
for (let num = possibleChild; num !== -1; num = behaviorTree.parentIndex[num]) {
if (num === possibleParent) {
return true;
}
}
return false;
}
/***
* 执行节点事件
*/
emitEvent(behaviorTree, nodeData, lifeCycle) {
const dump = nodeData.event[lifeCycle];
const nodeUuid = dump.node;
const compUuid = dump.comp;
const methodName = dump.method;
const methodData = dump.data;
if (!nodeUuid || !compUuid || !methodName) {
return [false, null];
}
// 行为树组件所在cocos节点
const curNode = behaviorTree.behavior.node;
// 先从当前节点开始层序遍历
let target = (0, utils_1.bfsCcNode)(curNode, nodeUuid);
// 找不到再从scene节点开始层序遍历
if (!target) {
target = (0, utils_1.bfsCcNode)(cc_1.director.getScene(), nodeUuid, curNode.uuid);
}
if (!target) {
return [false, null];
}
const comp = target._components.find((comp) => comp.uuid === compUuid);
if (!comp) {
return [false, null];
}
const method = comp[methodName];
if (!method) {
return [false, null];
}
const res = method.call(comp, methodData);
// 用户忘记写返回值,一律返回失败
const result = res !== undefined ? res : node_1.NodeStatus.Failure;
return [true, result];
}
};
BehaviorManager.instance = null;
BehaviorManager = BehaviorManager_1 = __decorate([
ccclass("BehaviorManager")
], BehaviorManager);
exports.BehaviorManager = BehaviorManager;
/***
* 行为树数据结构具体执行逻辑由BehaviorManager驱动
*/
class BehaviorTree {
constructor() {
this.activeStack = [];
this.nodeList = [];
//当前节点的父节点
this.parentIndex = [];
//当前节点的子节点
this.childrenIndex = [];
/***
* 为了实现中断
*/
//当前节点是父节点的第几个子节点
this.relativeChildIndex = [];
//当前节点的父组合节点
this.parentCompositeIndex = [];
//当前节点的子条件节点
this.childConditionalIndex = [];
//所有条件重评估
this.conditionalReevaluate = [];
//条件重评估id的map
this.conditionalReevaluateMap = new Map();
}
}
/***
* 条件重评估数据结构
* 各种情况讲解:
* 1、LowerPriority左侧的重评估条件可以打断右侧Action节点的运行不过不是所有都能打断当Action属于该compositeIndex所管理的子树才能打断
* 因此随着compositeIndex逐渐上移该条件能打断的范围就会越大当然这就需要此条件的父节点均有LowerPriority或者Both才能让compositeIndex一直上移
* 2、Self只能打断跟自己同一Composite节点下的其他节点的运行当该Composite被popNode时条件也会被删除
* 3、ParallelParallel下有多个分支都有LowerPriority的条件重评估对象
* 情况1、假设某个分支返回Running状态此时这个分支下的compositeIndex未达到并行节点无法管理其他分支下Action运行
* 情况2返回Success或者Failure状态当该运行栈最后一个元素popNode出去时此时栈为空会删除其管理的条件重评估
* 如果该条件的compositeIndex是-1不会进入compositeIndex上移逻辑因此也无法运行
* 总结:某个并行节点下的多个并行分支,各自的条件不会干扰
*/
class ConditionalReevaluate {
constructor(index, stackIndex, status, compositeIndex) {
this.index = index;
this.stackIndex = stackIndex;
this.status = status;
this.compositeIndex = compositeIndex;
}
}

77
dist/runtime/core/BehaviorSource.js vendored Normal file
View File

@@ -0,0 +1,77 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BehaviorSource = void 0;
const index_1 = require("../node/index");
const decorator_1 = require("./decorator");
const utils_1 = require("./utils");
/***
* 主要用来解析json文件生成行为树对象
*/
class BehaviorSource {
constructor() {
this.rootNode = null;
}
parse(content = {}) {
var _a;
try {
// root节点已存在代表已经成功解析过
if (this.rootNode) {
return;
}
const nodes = content.nodes;
if (!(nodes === null || nodes === void 0 ? void 0 : nodes.length)) {
throw new Error("节点数据不存在");
}
const nodesMap = new Map();
for (const node of nodes) {
nodesMap.set(node.id, node);
}
/***
* 建树(数据层面)
*/
const root = (0, utils_1.buildTree)(nodes);
if (!root) {
throw new Error("根节点不存在");
}
/***
* 建树(对象层面)
*/
const postOrderNodes = (0, utils_1.postOrder)(root);
// 节点id和对象的映射
const nodeIdInstanceMap = new Map();
// 倒序遍历
for (let i = 0; i < postOrderNodes.length; i++) {
const node = postOrderNodes[i];
// 获取节点对应的class
const cls = decorator_1.nodeClsMap.get(node.type);
if (!cls) {
throw new Error("节点class不存在");
}
// 实例化
const instance = new cls();
const nodeData = nodesMap.get(node.id);
// 保存node data
instance.data = nodeData;
// composite设置设置abortType
if (instance instanceof index_1.Composite) {
instance.abortType = nodeData.abortType;
}
// 父节点
if ((_a = node.children) === null || _a === void 0 ? void 0 : _a.length) {
// 倒序遍历可以保证子节点的初始化在父节点之前
const children = node.children.map((child) => nodeIdInstanceMap.get(child.id));
instance.setChildren(children);
}
nodeIdInstanceMap.set(node.id, instance);
// 最后一项是根节点
if (i === postOrderNodes.length - 1) {
this.rootNode = instance;
}
}
}
catch (e) {
console.error(e);
}
}
}
exports.BehaviorSource = BehaviorSource;

150
dist/runtime/core/BehaviorTree.js vendored Normal file
View File

@@ -0,0 +1,150 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BehaviorTree = exports.BehaviorTreeEvent = void 0;
const cc_1 = require("cc");
const node_1 = require("../node");
const BehaviorEditor_1 = require("./BehaviorEditor");
const BehaviorManager_1 = require("./BehaviorManager");
const BehaviorSource_1 = require("./BehaviorSource");
const { ccclass, property, requireComponent } = cc_1._decorator;
var BehaviorTreeEvent;
(function (BehaviorTreeEvent) {
BehaviorTreeEvent[BehaviorTreeEvent["BehaviorTreeStart"] = 0] = "BehaviorTreeStart";
BehaviorTreeEvent[BehaviorTreeEvent["BehaviorTreeEnd"] = 1] = "BehaviorTreeEnd";
})(BehaviorTreeEvent = exports.BehaviorTreeEvent || (exports.BehaviorTreeEvent = {}));
/***
* 用户真正使用的组件,用来设置单个行为树的运行参数
*/
let BehaviorTree = class BehaviorTree extends cc_1.Component {
constructor() {
super(...arguments);
this.asset = null;
this.restartWhenComplete = false;
this.startWhenEnabled = true;
/***
* true节点失活的时候行为树会保留仅暂停运行
* false节点失活的时候行为树直接删除
*/
this.pauseWhenDisabled = false;
this.logNodeChange = false;
// 是否被暂停运行了(未开始执行的行为树或者被删除的树都不属于暂停)
this.isPaused = false;
// 是否执行完start生成周期防止start和onEnable重复执行enableBehavior
this.isInit = false;
this.behaviorSource = new BehaviorSource_1.BehaviorSource();
this.map = new Map();
// 当前行为树状态
this.status = node_1.NodeStatus.Inactive;
}
onLoad() {
// 解析json文件
this.behaviorSource.parse(this.asset.json);
}
/***
* 仅enableBehavior和disableBehavior属于供用户在自定义脚本中管理单个行为树的方法
* 其他方法请勿使用
*/
enableBehavior() {
this.createBehaviorManager();
if (BehaviorManager_1.BehaviorManager.instance) {
BehaviorManager_1.BehaviorManager.instance.enableBehavior(this);
}
}
disableBehavior(pause = this.pauseWhenDisabled) {
if (BehaviorManager_1.BehaviorManager.instance) {
BehaviorManager_1.BehaviorManager.instance.disableBehavior(this, pause);
this.isPaused = pause;
}
}
start() {
if (this.startWhenEnabled) {
this.enableBehavior();
}
this.isInit = true;
}
onEnable() {
if (!this.isInit) {
return;
}
// 运行被暂停或者startWhenEnabled的树
if (this.isPaused || this.startWhenEnabled) {
this.enableBehavior();
this.isPaused = false;
}
}
onDisable() {
this.disableBehavior();
}
createBehaviorManager() {
if (!BehaviorManager_1.BehaviorManager.instance) {
const node = new cc_1.Node("BehaviorManager");
BehaviorManager_1.BehaviorManager.instance = node.addComponent(BehaviorManager_1.BehaviorManager);
cc_1.director.getScene().addChild(node);
}
}
/***
* 发布订阅
*/
on(event, cb, ctx) {
if (this.map.has(event)) {
this.map.get(event).push({ cb, ctx });
}
else {
this.map.set(event, [{ cb, ctx }]);
}
}
off(event, cb, ctx) {
if (this.map.has(event)) {
const index = this.map.get(event).findIndex((i) => cb === i.cb && i.ctx === ctx);
index > -1 && this.map.get(event).splice(index, 1);
}
}
emit(event, ...params) {
if (this.map.has(event)) {
this.map.get(event).forEach(({ cb, ctx }) => {
cb.apply(ctx, params);
});
}
}
clear() {
this.map.clear();
}
/***
* 插件面板初始化时调用
*/
async getAssetUrl() {
if (!this.asset) {
return;
}
const uuid = this.asset._uuid;
// 获取当前json的url
const url = await Editor.Message.request("asset-db", "query-url", uuid);
return url;
}
};
__decorate([
property(cc_1.JsonAsset)
], BehaviorTree.prototype, "asset", void 0);
__decorate([
property(cc_1.CCBoolean)
], BehaviorTree.prototype, "restartWhenComplete", void 0);
__decorate([
property(cc_1.CCBoolean)
], BehaviorTree.prototype, "startWhenEnabled", void 0);
__decorate([
property(cc_1.CCBoolean)
], BehaviorTree.prototype, "pauseWhenDisabled", void 0);
__decorate([
property(cc_1.CCBoolean)
], BehaviorTree.prototype, "logNodeChange", void 0);
BehaviorTree = __decorate([
ccclass("BehaviorTree"),
requireComponent(BehaviorEditor_1.BehaviorEditor)
], BehaviorTree);
exports.BehaviorTree = BehaviorTree;

26
dist/runtime/core/Blackboard.js vendored Normal file
View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Blackboard = void 0;
/***
* 黑板用来存储行为树所有信息
* 暴露静态方法方便用户使用
*/
class Blackboard {
static write(key, value) {
this.map.set(key, value);
}
static read(key) {
return this.map.get(key);
}
static has(key) {
return this.map.has(key);
}
static delete(key) {
return this.map.delete(key);
}
static clear() {
this.map.clear();
}
}
exports.Blackboard = Blackboard;
Blackboard.map = new Map();

7
dist/runtime/core/base/Action.js vendored Normal file
View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Action = void 0;
const Node_1 = require("./Node");
class Action extends Node_1.Node {
}
exports.Action = Action;

12
dist/runtime/core/base/Composite.js vendored Normal file
View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Composite = void 0;
const enum_1 = require("../enum");
const ParentNode_1 = require("./ParentNode");
class Composite extends ParentNode_1.ParentNode {
constructor(children = [], abortType = enum_1.AbortType.None) {
super(children);
this.abortType = abortType;
}
}
exports.Composite = Composite;

7
dist/runtime/core/base/Condition.js vendored Normal file
View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Condition = void 0;
const Node_1 = require("./Node");
class Condition extends Node_1.Node {
}
exports.Condition = Condition;

7
dist/runtime/core/base/Decorator.js vendored Normal file
View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Decorator = void 0;
const ParentNode_1 = require("./ParentNode");
class Decorator extends ParentNode_1.ParentNode {
}
exports.Decorator = Decorator;

25
dist/runtime/core/base/Node.js vendored Normal file
View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Node = void 0;
const enum_1 = require("../enum");
class Node {
constructor() {
this._status = enum_1.NodeStatus.Inactive;
}
get status() {
return this._status;
}
set status(newStatus) {
this._status = newStatus;
}
onStart() {
this.status = enum_1.NodeStatus.Running;
}
onUpdate() {
return enum_1.NodeStatus.Success;
}
onEnd() {
this.status = enum_1.NodeStatus.Inactive;
}
}
exports.Node = Node;

30
dist/runtime/core/base/ParentNode.js vendored Normal file
View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParentNode = void 0;
const Node_1 = require("./Node");
class ParentNode extends Node_1.Node {
get index() {
return this._index;
}
set index(data) {
this._index = data;
}
constructor(children) {
super();
this.children = [];
this._index = 0;
this.children = children;
}
setChildren(children) {
this.children = children;
}
onConditionalAbort(childIndex) { }
decorate(status) {
return status;
}
canRunParallelChildren() {
return false;
}
onChildStarted() { }
}
exports.ParentNode = ParentNode;

22
dist/runtime/core/base/index.js vendored Normal file
View File

@@ -0,0 +1,22 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./Node"), exports);
__exportStar(require("./Action"), exports);
__exportStar(require("./Composite"), exports);
__exportStar(require("./Condition"), exports);
__exportStar(require("./Decorator"), exports);
__exportStar(require("./ParentNode"), exports);

25
dist/runtime/core/biz/Action/Log.js vendored Normal file
View File

@@ -0,0 +1,25 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Log = void 0;
const index_1 = require("../../index");
let Log = class Log extends index_1.Action {
constructor(text = "log") {
super();
this.text = "log";
this.text = text;
}
onUpdate() {
console.log(this.text);
return index_1.NodeStatus.Success;
}
};
Log = __decorate([
(0, index_1.btclass)("Log")
], Log);
exports.Log = Log;

34
dist/runtime/core/biz/Action/Wait.js vendored Normal file
View File

@@ -0,0 +1,34 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Wait = void 0;
const index_1 = require("../../index");
let Wait = class Wait extends index_1.Action {
constructor(duration = 4000) {
super();
this.startTime = 0;
this.duration = 2000;
this.duration = duration;
}
onUpdate() {
return index_1.NodeStatus.Success;
return index_1.NodeStatus.Running;
}
onStart() {
super.onStart();
console.log("Wait onStart");
}
onEnd() {
super.onEnd();
console.log("Wait onEnd");
}
};
Wait = __decorate([
(0, index_1.btclass)("Wait")
], Wait);
exports.Wait = Wait;

18
dist/runtime/core/biz/Action/index.js vendored Normal file
View File

@@ -0,0 +1,18 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./Log"), exports);
__exportStar(require("./Wait"), exports);

View File

@@ -0,0 +1,59 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../../index");
let Parallel = class Parallel extends index_1.Composite {
constructor() {
super(...arguments);
this.executionStatus = [];
}
get status() {
let childrenComplete = true;
for (let i = 0; i < this.executionStatus.length; i++) {
if (this.executionStatus[i] == index_1.NodeStatus.Running) {
childrenComplete = false;
}
else if (this.executionStatus[i] == index_1.NodeStatus.Failure) {
return index_1.NodeStatus.Failure;
}
}
return childrenComplete ? index_1.NodeStatus.Success : index_1.NodeStatus.Running;
}
set status(_) { }
onConditionalAbort(childIndex) {
this.index = 0;
for (let i = 0; i < this.executionStatus.length; i++) {
this.executionStatus[i] = index_1.NodeStatus.Inactive;
}
}
onStart() {
super.onStart();
this.executionStatus = new Array(this.children.length);
this.index = 0;
for (let i = 0; i < this.executionStatus.length; i++) {
this.executionStatus[i] = index_1.NodeStatus.Inactive;
}
}
canRunParallelChildren() {
return true;
}
onChildStarted() {
this.executionStatus[this.index] = index_1.NodeStatus.Running;
this.index++;
}
canExecute() {
return this.index < this.children.length;
}
onChildExecuted(status, index) {
this.executionStatus[index] = status;
}
};
Parallel = __decorate([
(0, index_1.btclass)("Parallel")
], Parallel);
exports.default = Parallel;

View File

@@ -0,0 +1,84 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../../index");
let RandomSequence = class RandomSequence extends index_1.Composite {
constructor() {
super(...arguments);
this.executionOrder = [];
}
get index() {
return this.executionOrder[this.executionOrder.length - 1];
}
onStart() {
super.onStart();
this.shuffle();
}
canExecute() {
return Boolean(this.executionOrder.length) && this.status !== index_1.NodeStatus.Failure;
}
onChildExecuted(status, _) {
switch (status) {
case index_1.NodeStatus.Success:
this.executionOrder.pop();
if (this.executionOrder.length <= 0) {
this.status = index_1.NodeStatus.Success;
}
else {
this.status = index_1.NodeStatus.Running;
}
break;
case index_1.NodeStatus.Failure:
this.status = index_1.NodeStatus.Failure;
break;
case index_1.NodeStatus.Running:
this.status = index_1.NodeStatus.Running;
break;
default:
break;
}
}
onConditionalAbort() { }
// onUpdate(): NodeStatus {
// if (this.status === NodeStatus.Failure) {
// return NodeStatus.Failure
// }
//
// if (!this.executionOrder.length) {
// this.status = NodeStatus.Success
// return NodeStatus.Success
// }
//
// const node = this.children[this.index]
//
// const res = node.run()
//
// if (res === NodeStatus.Failure) {
// this.status = NodeStatus.Failure
// return NodeStatus.Failure
// }
//
// if (res === NodeStatus.Success) {
// this.executionOrder.pop()
// }
//
// return NodeStatus.Running
// }
shuffle() {
this.executionOrder = [];
const indexList = Array.from({ length: this.children.length }, (e, i) => i);
for (let i = indexList.length - 1; i >= 0; i--) {
const num = Math.floor(Math.random() * indexList.length);
this.executionOrder.push(indexList.splice(num, 1)[0]);
}
}
};
RandomSequence = __decorate([
(0, index_1.btclass)("RandomSequence")
], RandomSequence);
exports.default = RandomSequence;

View File

@@ -0,0 +1,47 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../../index");
let Selector = class Selector extends index_1.Composite {
onStart() {
super.onStart();
this.index = 0;
}
canExecute() {
return this.index < this.children.length && this.status !== index_1.NodeStatus.Success;
}
onChildExecuted(status, _) {
switch (status) {
case index_1.NodeStatus.Success:
this.status = index_1.NodeStatus.Success;
break;
case index_1.NodeStatus.Failure:
this.index++;
if (this.index >= this.children.length) {
this.status = index_1.NodeStatus.Failure;
}
else {
this.status = index_1.NodeStatus.Running;
}
break;
case index_1.NodeStatus.Running:
this.status = index_1.NodeStatus.Running;
break;
default:
break;
}
}
onConditionalAbort(index) {
this.index = index;
this.status = index_1.NodeStatus.Inactive;
}
};
Selector = __decorate([
(0, index_1.btclass)("Selector")
], Selector);
exports.default = Selector;

View File

@@ -0,0 +1,47 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../../index");
let Sequence = class Sequence extends index_1.Composite {
onStart() {
super.onStart();
this.index = 0;
}
canExecute() {
return this.index < this.children.length && this.status !== index_1.NodeStatus.Failure;
}
onChildExecuted(status, _) {
switch (status) {
case index_1.NodeStatus.Success:
this.index++;
if (this.index >= this.children.length) {
this.status = index_1.NodeStatus.Success;
}
else {
this.status = index_1.NodeStatus.Running;
}
break;
case index_1.NodeStatus.Failure:
this.status = index_1.NodeStatus.Failure;
break;
case index_1.NodeStatus.Running:
this.status = index_1.NodeStatus.Running;
break;
default:
break;
}
}
onConditionalAbort(index) {
this.index = index;
this.status = index_1.NodeStatus.Inactive;
}
};
Sequence = __decorate([
(0, index_1.btclass)("Sequence")
], Sequence);
exports.default = Sequence;

View File

@@ -0,0 +1,20 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./Sequence"), exports);
__exportStar(require("./Selector"), exports);
__exportStar(require("./Parallel"), exports);
__exportStar(require("./RandomSequence"), exports);

View File

@@ -0,0 +1,22 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../../index");
let ConditionHP = class ConditionHP extends index_1.Condition {
onUpdate() {
// console.log("Blackboard.Instance.hp", Blackboard.Instance.hp, "ConditionHP", Blackboard.Instance.hp >= 100);
// if (Blackboard.Instance.hp >= 100) {
// return NodeStatus.Success;
// }
return index_1.NodeStatus.Success;
}
};
ConditionHP = __decorate([
(0, index_1.btclass)("ConditionHP")
], ConditionHP);
exports.default = ConditionHP;

View File

@@ -0,0 +1,17 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./ConditionHP"), exports);

View File

@@ -0,0 +1,32 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Inverter = void 0;
const index_1 = require("../../index");
let Inverter = class Inverter extends index_1.Decorator {
canExecute() {
return this.status === index_1.NodeStatus.Inactive || this.status === index_1.NodeStatus.Running;
}
onChildExecuted(_, status) {
this.status = status;
}
decorate(status) {
switch (status) {
case index_1.NodeStatus.Success:
return index_1.NodeStatus.Failure;
case index_1.NodeStatus.Failure:
return index_1.NodeStatus.Success;
default:
return status;
}
}
};
Inverter = __decorate([
(0, index_1.btclass)("Inverter")
], Inverter);
exports.Inverter = Inverter;

View File

@@ -0,0 +1,36 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Repeater = void 0;
const index_1 = require("../../index");
let Repeater = class Repeater extends index_1.Decorator {
constructor(children, repeatCount = Infinity, endOnFailure = false) {
super(children);
this.repeatCount = Infinity;
this.curCount = 0;
this.endOnFailure = false;
this.repeatCount = repeatCount;
this.endOnFailure = endOnFailure;
}
canExecute() {
return (this.curCount < this.repeatCount &&
(!this.endOnFailure || (this.endOnFailure && this.status !== index_1.NodeStatus.Failure)));
}
onChildExecuted(status) {
this.curCount++;
this.status = status;
}
onStart() {
super.onStart();
this.curCount = 0;
}
};
Repeater = __decorate([
(0, index_1.btclass)("Repeater")
], Repeater);
exports.Repeater = Repeater;

View File

@@ -0,0 +1,30 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UntilSuccess = void 0;
const index_1 = require("../../index");
let UntilSuccess = class UntilSuccess extends index_1.Decorator {
canExecute() {
return this.status == index_1.NodeStatus.Inactive || this.status == index_1.NodeStatus.Failure;
}
onChildExecuted(status) {
this.status = this.decorate(status);
}
onUpdate() {
// let status: NodeStatus = (this.children[0] as Action | BTCondition).run();
// if (status === NodeStatus.Failure) {
// status = NodeStatus.Running;
// }
// return this.decorate(status);
return index_1.NodeStatus.Success;
}
};
UntilSuccess = __decorate([
(0, index_1.btclass)("UntilSuccess")
], UntilSuccess);
exports.UntilSuccess = UntilSuccess;

View File

@@ -0,0 +1,19 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./Inverter"), exports);
__exportStar(require("./Repeater"), exports);
__exportStar(require("./UntilSuccess"), exports);

20
dist/runtime/core/biz/index.js vendored Normal file
View File

@@ -0,0 +1,20 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./action"), exports);
__exportStar(require("./composite"), exports);
__exportStar(require("./decorator"), exports);
__exportStar(require("./condition"), exports);

13
dist/runtime/core/decorator.js vendored Normal file
View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.btclass = exports.nodeClsMap = void 0;
exports.nodeClsMap = new Map();
/***
* 收集被装饰的类用来在运行时通过节点类型找到对应的class
*/
const btclass = (name) => {
return function (target) {
exports.nodeClsMap.set(name, target);
};
};
exports.btclass = btclass;

13
dist/runtime/core/decorator/index.js vendored Normal file
View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.btclass = exports.nodeClsMap = void 0;
exports.nodeClsMap = new Map();
/***
* 收集被装饰的类用来在运行时通过节点类型找到对应的class
*/
const btclass = (name) => {
return function (target) {
exports.nodeClsMap.set(name, target);
};
};
exports.btclass = btclass;

17
dist/runtime/core/enum/index.js vendored Normal file
View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbortType = exports.NodeStatus = void 0;
var NodeStatus;
(function (NodeStatus) {
NodeStatus[NodeStatus["Inactive"] = 0] = "Inactive";
NodeStatus[NodeStatus["Running"] = 1] = "Running";
NodeStatus[NodeStatus["Success"] = 2] = "Success";
NodeStatus[NodeStatus["Failure"] = 3] = "Failure";
})(NodeStatus = exports.NodeStatus || (exports.NodeStatus = {}));
var AbortType;
(function (AbortType) {
AbortType[AbortType["None"] = 0] = "None";
AbortType[AbortType["LowerPriority"] = 1] = "LowerPriority";
AbortType[AbortType["Self"] = 2] = "Self";
AbortType[AbortType["Both"] = 3] = "Both";
})(AbortType = exports.AbortType || (exports.AbortType = {}));

23
dist/runtime/core/index.js vendored Normal file
View File

@@ -0,0 +1,23 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./BehaviorSource"), exports);
__exportStar(require("./BehaviorTree"), exports);
__exportStar(require("./BehaviorEditor"), exports);
__exportStar(require("./BehaviorManager"), exports);
__exportStar(require("./Blackboard"), exports);
__exportStar(require("./decorator"), exports);
__exportStar(require("./utils"), exports);

120
dist/runtime/core/utils.js vendored Normal file
View File

@@ -0,0 +1,120 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deepClone = exports.preOrder = exports.bfsCcNode = exports.buildTree = exports.postOrder = void 0;
/***
* N叉树的倒序遍历
*/
const postOrder = function (root) {
if (!root) {
return [];
}
const stack = [root];
const stack2 = [];
const result = [];
while (stack.length) {
const node = stack.pop();
stack2.push(node);
for (let i = 0; i < node.children.length; i++) {
stack.push(node.children[i]);
}
}
while (stack2.length) {
result.push(stack2.pop());
}
return result;
};
exports.postOrder = postOrder;
/**
* 数组转树,返回根节点
* @param nodes
* @returns root
*/
const buildTree = (_nodes) => {
// 防止修改有原数据
const nodes = (0, exports.deepClone)(_nodes);
const nodeMap = new Map();
let root = null;
// 记录id和node数据的映射
for (const node of nodes) {
if (node.isRoot) {
root = node;
}
nodeMap.set(node.id, node);
}
// 没有根节点
if (!root) {
return null;
}
// 把children中的Id换成真正的node数据
for (const node of nodes) {
node.children = node.children.map((childId) => nodeMap.get(childId));
}
// 返回根节点
return root;
};
exports.buildTree = buildTree;
/***
* BFS开始
* 从当前节点开始层序遍历
* 找不到再从scene节点开始层序遍历
* dirtyNode代表需要跳过的节点避免scene场景重复遍历curNode
*/
const bfsCcNode = (root, targetUuid, dirtyUuid) => {
let target = null;
let queue = [root];
// 给while循环起名
myWhile: while (queue.length) {
const len = queue.length;
for (let i = 0; i < len; i++) {
const item = queue.pop();
const uuid = item.uuid;
if (uuid === targetUuid) {
target = item;
// 找到目标直接退出while循环
break myWhile;
}
for (let j = 0; j < item.children.length; j++) {
const child = item.children[j];
// 跳过已经遍历过的节点
if (dirtyUuid && child.uuid === dirtyUuid) {
continue;
}
queue.unshift(child);
}
}
}
return target;
};
exports.bfsCcNode = bfsCcNode;
const preOrder = function (root) {
if (!root) {
return [];
}
var stack = [root];
var result = [];
while (stack.length) {
const item = stack.pop();
for (let i = item.children.length - 1; i >= 0; i--) {
stack.push(item.children[i]);
}
result.push(item);
}
return result;
};
exports.preOrder = preOrder;
/***
* 深克隆
*/
const deepClone = (obj) => {
if (typeof obj !== "object" || obj === null) {
return obj;
}
const res = Array.isArray(obj) ? [] : {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
res[key] = (0, exports.deepClone)(obj[key]);
}
}
return res;
};
exports.deepClone = deepClone;

65
dist/runtime/core/utils/index.js vendored Normal file
View File

@@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildTree = exports.postOrder = exports.hit = exports.clamp = exports.uuid = exports.getParentCls = void 0;
// 获取父类构造函数(ts:constructor === class)
const getParentCls = (cls) => { var _a; return cls && ((_a = cls.prototype.__proto__) === null || _a === void 0 ? void 0 : _a.constructor); };
exports.getParentCls = getParentCls;
// 生成节点uuid
const uuid = () => Editor.Utils.UUID.generate();
exports.uuid = uuid;
// 防止越界
const clamp = (value, max, min) => (value < min ? min : value > max ? max : value);
exports.clamp = clamp;
// 是否命中
const hit = (x, y, targetX, targetY, targetW, targetH) => x > targetX && y > targetY && x < targetX + targetW && y < targetY + targetH;
exports.hit = hit;
/***
* N叉树的倒序遍历
*/
const postOrder = function (root) {
if (!root) {
return [];
}
var stack = [root];
var stack2 = [];
var result = [];
while (stack.length) {
const node = stack.pop();
stack2.push(node);
for (let i = 0; i < node.children.length; i++) {
stack.push(node.children[i]);
}
}
while (stack2.length) {
result.push(stack2.pop());
}
return result;
};
exports.postOrder = postOrder;
/**
* 数组转树,返回根节点
* @param nodes
* @returns root
*/
const buildTree = (nodes) => {
const nodeIdMap = new Map();
let root = null;
// 记录id和node数据的映射
for (const node of nodes) {
if (node.isRoot) {
root = node;
}
nodeIdMap.set(node.id, node);
}
// 没有根节点
if (!root) {
return null;
}
// 把children中的Id换成真正的node数据
for (const node of nodes) {
node.children = node.children.map((childId) => nodeIdMap.get(childId));
}
// 返回根节点
return root;
};
exports.buildTree = buildTree;